From 70e5393702c4289e72305563160a9f0594d4bc5b Mon Sep 17 00:00:00 2001 From: miteruzo Date: Tue, 10 Feb 2026 00:12:22 +0900 Subject: [PATCH 1/3] #258 --- .../app/controllers/nico_tags_controller.rb | 4 +++- backend/app/controllers/tags_controller.rb | 23 +++++++++++++++---- .../app/controllers/wiki_pages_controller.rb | 6 ++++- 3 files changed, 26 insertions(+), 7 deletions(-) diff --git a/backend/app/controllers/nico_tags_controller.rb b/backend/app/controllers/nico_tags_controller.rb index da3d831..b6acaf2 100644 --- a/backend/app/controllers/nico_tags_controller.rb +++ b/backend/app/controllers/nico_tags_controller.rb @@ -6,7 +6,9 @@ class NicoTagsController < ApplicationController cursor = params[:cursor].presence q = Tag.nico_tags - .includes(:tag_name, linked_tags: :tag_name) + .joins(:tag_name) + .left_joins(tag_name: :wiki_page) + .includes(:tag_name, tag_name: :wiki_page, linked_tags: :tag_name) .order(updated_at: :desc) q = q.where('tags.updated_at < ?', Time.iso8601(cursor)) if cursor diff --git a/backend/app/controllers/tags_controller.rb b/backend/app/controllers/tags_controller.rb index 1c5dcb2..a504f10 100644 --- a/backend/app/controllers/tags_controller.rb +++ b/backend/app/controllers/tags_controller.rb @@ -4,10 +4,15 @@ class TagsController < ApplicationController tags = if post_id.present? - Tag.joins(:posts).where(posts: { id: post_id }) + Tag.joins(:posts, :tag_name) else - Tag.all + Tag.joins(:tag_name) end + .left_joins(tag_name: :wiki_page) + .includes(:tag_name, tag_name: :wiki_page) + if post_id.present? + tags = tags.where(posts: { id: post_id }) + end render json: tags.as_json(only: [:id, :category, :post_count], methods: [:name, :has_wiki]) end @@ -33,7 +38,9 @@ class TagsController < ApplicationController matched_alias_by_tag_name_id[canonical_id] ||= alias_name end - base = Tag.joins(:tag_name).includes(:tag_name) + base = Tag.joins(:tag_name) + .left_joins(tag_name: :wiki_page) + .includes(:tag_name, tag_name: :wiki_page) base = base.where('tags.post_count > 0') if present_only canonical_hit = @@ -58,7 +65,10 @@ class TagsController < ApplicationController end def show - tag = Tag.find_by(id: params[:id]) + tag = Tag.joins(:tag_name) + .left_joins(tag_name: :wiki_page) + .includes(:tag_name, tag_name: :wiki_page) + .find_by(id: params[:id]) if tag render json: tag.as_json(only: [:id, :category, :post_count], methods: [:name, :has_wiki]) else @@ -70,7 +80,10 @@ class TagsController < ApplicationController name = params[:name].to_s.strip return head :bad_request if name.blank? - tag = Tag.joins(:tag_name).includes(:tag_name).find_by(tag_names: { name: }) + tag = Tag.joins(:tag_name) + .left_joins(tag_name: :wiki_page) + .includes(:tag_name, tag_name: :wiki_page) + .find_by(tag_names: { name: }) if tag render json: tag.as_json(only: [:id, :category, :post_count], methods: [:name, :has_wiki]) else diff --git a/backend/app/controllers/wiki_pages_controller.rb b/backend/app/controllers/wiki_pages_controller.rb index 20b2912..e9960ed 100644 --- a/backend/app/controllers/wiki_pages_controller.rb +++ b/backend/app/controllers/wiki_pages_controller.rb @@ -3,7 +3,11 @@ class WikiPagesController < ApplicationController def index title = params[:title].to_s.strip - return render json: WikiPage.all.as_json(methods: [:title]) if title.blank? + if title.blank? + return render json: WikiPage.joins(:tag_name) + .includes(:tag_name) + .as_json(methods: [:title]) + end q = WikiPage.joins(:tag_name).includes(:tag_name) .where('tag_names.name LIKE ?', "%#{ WikiPage.sanitize_sql_like(title) }%") -- 2.34.1 From 22f1fa5365c30906bfc3ef20337a0d7256780648 Mon Sep 17 00:00:00 2001 From: miteruzo Date: Tue, 10 Feb 2026 12:44:37 +0900 Subject: [PATCH 2/3] #258 --- backend/app/controllers/wiki_pages_controller.rb | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/backend/app/controllers/wiki_pages_controller.rb b/backend/app/controllers/wiki_pages_controller.rb index e9960ed..b1337bd 100644 --- a/backend/app/controllers/wiki_pages_controller.rb +++ b/backend/app/controllers/wiki_pages_controller.rb @@ -15,14 +15,16 @@ class WikiPagesController < ApplicationController end def show - page = WikiPage.find_by(id: params[:id]) + page = WikiPage.joins(:tag_name, :wiki_revisions, wiki_revisions: :wiki_revision_lines) + .includes(:tag_name, :wiki_revisions, wiki_revisions: :wiki_revision_lines) + .find_by(id: params[:id]) render_wiki_page_or_404 page end def show_by_title title = params[:title].to_s.strip - page = WikiPage.joins(:tag_name) - .includes(:tag_name) + page = WikiPage.joins(:tag_name, :wiki_revisions, wiki_revisions: :wiki_revision_lines) + .includes(:tag_name, :wiki_revisions, wiki_revisions: :wiki_revision_lines) .find_by(tag_names: { name: title }) render_wiki_page_or_404 page end -- 2.34.1 From 2d97aef84c1486ba8ded3347a516380017a74f1f Mon Sep 17 00:00:00 2001 From: miteruzo Date: Wed, 11 Feb 2026 02:31:12 +0900 Subject: [PATCH 3/3] #258 --- .../app/controllers/nico_tags_controller.rb | 6 +-- backend/app/controllers/posts_controller.rb | 43 +++++++++++-------- backend/app/controllers/tags_controller.rb | 4 -- .../app/controllers/wiki_pages_controller.rb | 18 ++++---- backend/app/models/post.rb | 10 +++-- backend/app/models/tag.rb | 4 +- 6 files changed, 46 insertions(+), 39 deletions(-) diff --git a/backend/app/controllers/nico_tags_controller.rb b/backend/app/controllers/nico_tags_controller.rb index b6acaf2..2b28175 100644 --- a/backend/app/controllers/nico_tags_controller.rb +++ b/backend/app/controllers/nico_tags_controller.rb @@ -6,13 +6,11 @@ class NicoTagsController < ApplicationController cursor = params[:cursor].presence q = Tag.nico_tags - .joins(:tag_name) - .left_joins(tag_name: :wiki_page) - .includes(:tag_name, tag_name: :wiki_page, linked_tags: :tag_name) + .includes(:tag_name, tag_name: :wiki_page, linked_tags: { tag_name: :wiki_page }) .order(updated_at: :desc) q = q.where('tags.updated_at < ?', Time.iso8601(cursor)) if cursor - tags = q.limit(limit + 1) + tags = q.limit(limit + 1).to_a next_cursor = nil if tags.size > limit diff --git a/backend/app/controllers/posts_controller.rb b/backend/app/controllers/posts_controller.rb index 57340eb..eb4dee6 100644 --- a/backend/app/controllers/posts_controller.rb +++ b/backend/app/controllers/posts_controller.rb @@ -17,16 +17,17 @@ class PostsController < ApplicationController 'posts.created_at)' q = filtered_posts - .preload(tags: :tag_name) + .preload(tags: { tag_name: :wiki_page }) .with_attached_thumbnail .select("posts.*, #{ sort_sql } AS sort_ts") .order(Arel.sql("#{ sort_sql } DESC")) - posts = ( + posts = if cursor q.where("#{ sort_sql } < ?", Time.iso8601(cursor)).limit(limit + 1) else q.limit(limit).offset(offset) - end).to_a + end + .to_a next_cursor = nil if cursor && posts.length > limit @@ -52,7 +53,9 @@ class PostsController < ApplicationController end def random - post = filtered_posts.preload(tags: :tag_name).order('RAND()').first + post = filtered_posts.preload(tags: { tag_name: :wiki_page }) + .order('RAND()') + .first return head :not_found unless post viewed = current_user&.viewed?(post) || false @@ -64,7 +67,7 @@ class PostsController < ApplicationController end def show - post = Post.includes(tags: :tag_name).find(params[:id]) + post = Post.includes(tags: { tag_name: :wiki_page }).find(params[:id]) return head :not_found unless post viewed = current_user&.viewed?(post) || false @@ -151,7 +154,7 @@ class PostsController < ApplicationController end def changes - id = params[:id] + id = params[:id].presence page = (params[:page].presence || 1).to_i limit = (params[:limit].presence || 20).to_i @@ -162,30 +165,34 @@ class PostsController < ApplicationController pts = PostTag.with_discarded pts = pts.where(post_id: id) if id.present? - pts = pts.includes(:post, { tag: :tag_name }, :created_user, :deleted_user) + pts = pts.includes(:post, :created_user, :deleted_user, + tag: { tag_name: :wiki_page }) events = [] pts.each do |pt| + tag = pt.tag.as_json(only: [:id, :category], methods: [:name, :has_wiki]) + post = pt.post + events << Event.new( - post: pt.post, - tag: pt.tag.as_json(only: [:id, :category], methods: [:name, :has_wiki]), - user: pt.created_user && { id: pt.created_user.id, name: pt.created_user.name }, - change_type: 'add', - timestamp: pt.created_at) + post:, + tag:, + user: pt.created_user && { id: pt.created_user.id, name: pt.created_user.name }, + change_type: 'add', + timestamp: pt.created_at) if pt.discarded_at events << Event.new( - post: pt.post, - tag: pt.tag.as_json(only: [:id, :category], methods: [:name, :has_wiki]), - user: pt.deleted_user && { id: pt.deleted_user.id, name: pt.deleted_user.name }, - change_type: 'remove', - timestamp: pt.discarded_at) + post:, + tag:, + user: pt.deleted_user && { id: pt.deleted_user.id, name: pt.deleted_user.name }, + change_type: 'remove', + timestamp: pt.discarded_at) end end events.sort_by!(&:timestamp) events.reverse! - render json: { changes: events.slice(offset, limit).as_json, count: events.size } + render json: { changes: (events.slice(offset, limit) || []).as_json, count: events.size } end private diff --git a/backend/app/controllers/tags_controller.rb b/backend/app/controllers/tags_controller.rb index a504f10..5251e72 100644 --- a/backend/app/controllers/tags_controller.rb +++ b/backend/app/controllers/tags_controller.rb @@ -8,7 +8,6 @@ class TagsController < ApplicationController else Tag.joins(:tag_name) end - .left_joins(tag_name: :wiki_page) .includes(:tag_name, tag_name: :wiki_page) if post_id.present? tags = tags.where(posts: { id: post_id }) @@ -39,7 +38,6 @@ class TagsController < ApplicationController end base = Tag.joins(:tag_name) - .left_joins(tag_name: :wiki_page) .includes(:tag_name, tag_name: :wiki_page) base = base.where('tags.post_count > 0') if present_only @@ -66,7 +64,6 @@ class TagsController < ApplicationController def show tag = Tag.joins(:tag_name) - .left_joins(tag_name: :wiki_page) .includes(:tag_name, tag_name: :wiki_page) .find_by(id: params[:id]) if tag @@ -81,7 +78,6 @@ class TagsController < ApplicationController return head :bad_request if name.blank? tag = Tag.joins(:tag_name) - .left_joins(tag_name: :wiki_page) .includes(:tag_name, tag_name: :wiki_page) .find_by(tag_names: { name: }) if tag diff --git a/backend/app/controllers/wiki_pages_controller.rb b/backend/app/controllers/wiki_pages_controller.rb index b1337bd..6dc4216 100644 --- a/backend/app/controllers/wiki_pages_controller.rb +++ b/backend/app/controllers/wiki_pages_controller.rb @@ -15,17 +15,17 @@ class WikiPagesController < ApplicationController end def show - page = WikiPage.joins(:tag_name, :wiki_revisions, wiki_revisions: :wiki_revision_lines) - .includes(:tag_name, :wiki_revisions, wiki_revisions: :wiki_revision_lines) + page = WikiPage.joins(:tag_name) + .includes(:tag_name) .find_by(id: params[:id]) render_wiki_page_or_404 page end def show_by_title title = params[:title].to_s.strip - page = WikiPage.joins(:tag_name, :wiki_revisions, wiki_revisions: :wiki_revision_lines) - .includes(:tag_name, :wiki_revisions, wiki_revisions: :wiki_revision_lines) - .find_by(tag_names: { name: title }) + page = WikiPage.joins(:tag_name) + .includes(:tag_name) + .find_by(tag_name: { name: title }) render_wiki_page_or_404 page end @@ -53,7 +53,7 @@ class WikiPagesController < ApplicationController from = params[:from].presence to = params[:to].presence - page = WikiPage.find(id) + page = WikiPage.joins(:tag_name).includes(:tag_name).find(id) from_rev = from && page.wiki_revisions.find(from) to_rev = to ? page.wiki_revisions.find(to) : page.current_revision @@ -137,7 +137,9 @@ class WikiPagesController < ApplicationController def changes id = params[:id].presence - q = WikiRevision.includes(:wiki_page, :created_user).order(id: :desc) + q = WikiRevision.joins(wiki_page: :tag_name) + .includes(:created_user, wiki_page: :tag_name) + .order(id: :desc) q = q.where(wiki_page_id: id) if id render json: q.limit(200).map { |rev| @@ -145,7 +147,7 @@ class WikiPagesController < ApplicationController pred: rev.base_revision_id, succ: nil, wiki_page: { id: rev.wiki_page_id, title: rev.wiki_page.title }, - user: { id: rev.created_user.id, name: rev.created_user.name }, + user: rev.created_user && { id: rev.created_user.id, name: rev.created_user.name }, kind: rev.kind, message: rev.message, timestamp: rev.created_at } diff --git a/backend/app/models/post.rb b/backend/app/models/post.rb index e25575f..c898615 100644 --- a/backend/app/models/post.rb +++ b/backend/app/models/post.rb @@ -30,13 +30,15 @@ class Post < ApplicationRecord super(options).merge(thumbnail: nil) end - def related(limit: nil) - ids = post_similarities.select(:target_post_id).order(cos: :desc) + def related limit: nil + ids = post_similarities.order(cos: :desc) ids = ids.limit(limit) if limit ids = ids.pluck(:target_post_id) - return [] if ids.empty? + return Post.none if ids.empty? - Post.where(id: ids).order(Arel.sql("FIELD(id, #{ ids.join(',') })")) + Post.where(id: ids) + .with_attached_thumbnail + .order(Arel.sql("FIELD(posts.id, #{ ids.join(',') })")) end def resized_thumbnail! diff --git a/backend/app/models/tag.rb b/backend/app/models/tag.rb index c4b36e6..60cc79b 100644 --- a/backend/app/models/tag.rb +++ b/backend/app/models/tag.rb @@ -25,6 +25,8 @@ class Tag < ApplicationRecord has_many :tag_similarities, dependent: :delete_all belongs_to :tag_name + delegate :wiki_page, to: :tag_name + delegate :name, to: :tag_name, allow_nil: true validates :tag_name, presence: true @@ -56,7 +58,7 @@ class Tag < ApplicationRecord end def has_wiki - tag_name&.wiki_page.present? + wiki_page.present? end def self.tagme -- 2.34.1