Skip to content
Snippets Groups Projects
Commit b661a9c6 authored by ArtOfCode-'s avatar ArtOfCode-
Browse files

This is a brilliant idea.

parent fdfe5073
Branches
Tags
No related merge requests found
......@@ -67,6 +67,7 @@ Set up the database:
rails db:create
rails db:schema:load
rails r db/scripts/create_tags_path_view.rb
rails db:migrate
rails db:seed
......
......@@ -23,9 +23,15 @@ class TagsController < ApplicationController
@tag_set = @category.tag_set
@tags = if params[:q].present?
@tag_set.tags.search(params[:q])
elsif params[:hierarchical].present?
@tag_set.tags_with_paths.order(:path)
else
@tag_set.tags.order(Arel.sql('COUNT(posts.id) DESC'))
end.left_joins(:posts).group(Arel.sql('tags.id')).select(Arel.sql('tags.*, COUNT(posts.id) AS post_count'))
end
@count = @tags.count
table = params[:hierarchical].present? ? 'tags_paths' : 'tags'
@tags = @tags.left_joins(:posts).group(Arel.sql("#{table}.id"))
.select(Arel.sql("#{table}.*, COUNT(posts.id) AS post_count"))
.paginate(per_page: 96, page: params[:page])
end
......@@ -65,9 +71,15 @@ class TagsController < ApplicationController
def children
@tags = if params[:q].present?
@tag.children.search(params[:q])
elsif params[:hierarchical].present?
@tag_set.tags_with_paths.order(:path)
else
@tag.children.order(Arel.sql('COUNT(posts.id) DESC'))
end.left_joins(:posts).group(Arel.sql('tags.id')).select(Arel.sql('tags.*, COUNT(posts.id) AS post_count'))
end
@count = @tags.count
table = params[:hierarchical].present? ? 'tags_paths' : 'tags'
@tags = @tags.left_joins(:posts).group(Arel.sql("#{table}.id"))
.select(Arel.sql("#{table}.*, COUNT(posts.id) AS post_count"))
.paginate(per_page: 96, page: params[:page])
end
......
......@@ -37,6 +37,19 @@ class ApplicationRecord < ActiveRecord::Base
ary = ary.map { |el| ActiveRecord::Base.sanitize_sql_array(['?', el]) }
"(#{ary.join(', ')})"
end
# This is a BRILLIANT idea. BRILLIANT, I tell you.
def self.with_lax_group_rules
return unless block_given?
transaction do
connection.execute "SET @old_sql_mode = @@sql_mode"
connection.execute "SET SESSION sql_mode = REPLACE(REPLACE(@@sql_mode, 'ONLY_FULL_GROUP_BY,', ''), " \
"'ONLY_FULL_GROUP_BY', '')"
yield
connection.execute "SET SESSION sql_mode = @old_sql_mode"
end
end
end
module UserSortable
......
......@@ -22,6 +22,16 @@ class Tag < ApplicationRecord
ActiveRecord::Base.connection.execute(query).to_a.map(&:first)
end
def parent_chain
Enumerator.new do |enum|
parent_group = group
while parent_group != nil
enum.yield parent_group
parent_group = parent_group.group
end
end
end
private
def parent_not_self
......
class TagSet < ApplicationRecord
include CommunityRelated
has_many :tags
has_many :tags_with_paths, class_name: 'TagWithPath'
has_many :categories
validates :name, uniqueness: { scope: [:community_id] }, presence: true
......
class TagWithPath < Tag
self.table_name = 'tags_paths'
end
\ No newline at end of file
......@@ -3,6 +3,7 @@
<% moderator_ids = @category&.moderator_tag_ids %>
<% topic_ids = @category&.topic_tag_ids %>
<% ApplicationRecord.with_lax_group_rules do %>
<% @tags.each do |tag| %>
<% required = required_ids&.include?(tag.id) ? 'is-filled' : '' %>
<% topic = topic_ids&.include?(tag.id) ? 'is-outlined' : '' %>
......@@ -10,4 +11,5 @@
<% classes = "badge is-tag #{required} #{topic} #{moderator}" %>
<%= render 'tag', category: @category, tag: tag, classes: classes %>
<% end %>
<% end %>
</div>
\ No newline at end of file
<div class="grid--cell is-4-lg is-6-md is-12-sm">
<% if tag.respond_to?(:path) && tag.path.present? %>
<span class="has-font-size-caption">
<% tag.path.split(' > ')[0..-2].each do |tag| %>
<span class="badge is-tag is-small is-muted"><%= tag %></span> &raquo;
<% end %>
</span>
<% end %>
<%= link_to tag.name, tag_path(id: category.id, tag_id: tag.id), class: classes %>
<span class="has-color-tertiary-900">&times; <%= tag.post_count %></span>
<span class="has-color-tertiary-900">&times;&nbsp;<%= tag.post_count %></span>
<% if tag.excerpt.present? %>
<p class="has-font-size-caption has-color-tertiary-900">
<% splat = split_words_max_length(tag.excerpt, 120) %>
......
......@@ -14,6 +14,18 @@
</div>
<% end %>
<% unless params[:q].present? %>
<div class="category-meta">
<h3><%= pluralize(@count, 'tag') %></h3>
<div class="button-list is-gutterless has-margin-2">
<%= link_to 'Usage', category_tags_path(@category),
class: "button is-muted is-outlined #{params[:hierarchical].nil? ? 'is-active' : ''}" %>
<%= link_to 'Hierarchy', query_url(hierarchical: '1'),
class: "button is-muted is-outlined #{params[:hierarchical].present? ? 'is-active' : ''}" %>
</div>
</div>
<% end %>
<%= render 'list' %>
<%= will_paginate @tags, renderer: BootstrapPagination::Rails %>
......@@ -14,6 +14,18 @@
</div>
<% end %>
<% unless params[:q].present? %>
<div class="category-meta">
<h3><%= pluralize(@count, 'tag') %></h3>
<div class="button-list is-gutterless has-margin-2">
<%= link_to 'Usage', category_tags_path(@category),
class: "button is-muted is-outlined #{params[:hierarchical].nil? ? 'is-active' : ''}" %>
<%= link_to 'Hierarchy', query_url(hierarchical: '1'),
class: "button is-muted is-outlined #{params[:hierarchical].present? ? 'is-active' : ''}" %>
</div>
</div>
<% end %>
<%= render 'list' %>
<%= will_paginate @tags, renderer: BootstrapPagination::Rails %>
class ActiveRecord::Relation
# Preload one level a chained association whose name is specified in attribute.
def preload_chain(attribute, collection: nil)
preloader = ActiveRecord::Associations::Preloader.new
preloader.preload(collection || records, attribute.to_sym)
self
end
# Preload all levels of a chained association specified in attribute. Will cause infinite loops if there are cycles.
def deep_preload_chain(attribute, collection: nil)
return if (collection || records).empty?
preload_chain(attribute, collection: collection)
deep_preload_chain(attribute, collection: (collection || records).select(&attribute.to_sym).map(&attribute.to_sym))
self
end
# Preload one level of a chained association on a table referenced by the current table.
def preload_reference_chain(**reference_attribs)
reference_attribs.each do |t, a|
preload_chain(a, collection: records.map { |r| r.public_send(t.to_sym) })
end
self
end
# Preload all levels (including infinite loops) of a chained association on a referenced table.
def deep_preload_reference_chain(**reference_attribs)
reference_attribs.each do |t, a|
deep_preload_chain(a, collection: records.map { |r| r.public_send(t.to_sym) })
end
self
end
end
\ No newline at end of file
ActiveRecord::Base.connection.execute File.read(Rails.root.join('db/scripts/create_tags_path_view.sql'))
\ No newline at end of file
create view tags_paths as
WITH RECURSIVE tag_path (id, created_at, updated_at, community_id, tag_set_id, wiki_markdown,
wiki, excerpt, parent_id, name, path) AS
(
SELECT id, created_at, updated_at, community_id, tag_set_id, wiki_markdown,
wiki, excerpt, parent_id, name, name as path
FROM tags
WHERE parent_id IS NULL
UNION ALL
SELECT t.id, t.created_at, t.updated_at, t.community_id, t.tag_set_id, t.wiki_markdown,
t.wiki, t.excerpt, t.parent_id, t.name, concat(tp.path, ' > ', t.name) as path
FROM tag_path AS tp JOIN tags AS t ON tp.id = t.parent_id
)
SELECT * FROM tag_path
ORDER BY path;
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please to comment