diff --git a/backend/app/controllers/nico_tags_controller.rb b/backend/app/controllers/nico_tags_controller.rb index da3d831..2b28175 100644 --- a/backend/app/controllers/nico_tags_controller.rb +++ b/backend/app/controllers/nico_tags_controller.rb @@ -6,11 +6,11 @@ class NicoTagsController < ApplicationController cursor = params[:cursor].presence q = Tag.nico_tags - .includes(:tag_name, 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 1c5dcb2..5251e72 100644 --- a/backend/app/controllers/tags_controller.rb +++ b/backend/app/controllers/tags_controller.rb @@ -4,10 +4,14 @@ 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 + .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 +37,8 @@ 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) + .includes(:tag_name, tag_name: :wiki_page) base = base.where('tags.post_count > 0') if present_only canonical_hit = @@ -58,7 +63,9 @@ class TagsController < ApplicationController end def show - tag = Tag.find_by(id: params[:id]) + tag = Tag.joins(:tag_name) + .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 +77,9 @@ 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) + .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..6dc4216 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) }%") @@ -11,7 +15,9 @@ class WikiPagesController < ApplicationController end def show - page = WikiPage.find_by(id: params[:id]) + page = WikiPage.joins(:tag_name) + .includes(:tag_name) + .find_by(id: params[:id]) render_wiki_page_or_404 page end @@ -19,7 +25,7 @@ class WikiPagesController < ApplicationController title = params[:title].to_s.strip page = WikiPage.joins(:tag_name) .includes(:tag_name) - .find_by(tag_names: { name: title }) + .find_by(tag_name: { name: title }) render_wiki_page_or_404 page end @@ -47,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 @@ -131,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| @@ -139,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