| @@ -1,9 +1,13 @@ | |||||
| class NicoTagsController < ApplicationController | class NicoTagsController < ApplicationController | ||||
| TAG_JSON = { only: [:id, :category, :post_count], methods: [:name, :has_wiki] }.freeze | |||||
| def index | def index | ||||
| limit = (params[:limit] || 20).to_i | limit = (params[:limit] || 20).to_i | ||||
| cursor = params[:cursor].presence | cursor = params[:cursor].presence | ||||
| q = Tag.nico_tags.includes(:linked_tags).order(updated_at: :desc) | |||||
| q = Tag.nico_tags | |||||
| .includes(:tag_name, linked_tags: :tag_name) | |||||
| .order(updated_at: :desc) | |||||
| q = q.where('tags.updated_at < ?', Time.iso8601(cursor)) if cursor | q = q.where('tags.updated_at < ?', Time.iso8601(cursor)) if cursor | ||||
| tags = q.limit(limit + 1) | tags = q.limit(limit + 1) | ||||
| @@ -15,7 +19,9 @@ class NicoTagsController < ApplicationController | |||||
| end | end | ||||
| render json: { tags: tags.map { |tag| | render json: { tags: tags.map { |tag| | ||||
| tag.as_json(include: :linked_tags) | |||||
| tag.as_json(TAG_JSON).merge(linked_tags: tag.linked_tags.map { |lt| | |||||
| lt.as_json(TAG_JSON) | |||||
| }) | |||||
| }, next_cursor: } | }, next_cursor: } | ||||
| end | end | ||||
| @@ -30,12 +36,11 @@ class NicoTagsController < ApplicationController | |||||
| linked_tag_names = params[:tags].to_s.split(' ') | linked_tag_names = params[:tags].to_s.split(' ') | ||||
| linked_tags = Tag.normalise_tags(linked_tag_names, with_tagme: false) | linked_tags = Tag.normalise_tags(linked_tag_names, with_tagme: false) | ||||
| return head :bad_request if linked_tags.filter { |t| t.category == 'nico' }.present? | |||||
| return head :bad_request if linked_tags.any? { |t| t.category == 'nico' } | |||||
| tag.linked_tags = linked_tags | tag.linked_tags = linked_tags | ||||
| tag.updated_at = Time.now | |||||
| tag.save! | tag.save! | ||||
| render json: tag.linked_tags, status: :ok | |||||
| render json: tag.linked_tags.map { |t| t.as_json(TAG_JSON) }, status: :ok | |||||
| end | end | ||||
| end | end | ||||
| @@ -158,7 +158,7 @@ class PostsController < ApplicationController | |||||
| pts.each do |pt| | pts.each do |pt| | ||||
| events << Event.new( | events << Event.new( | ||||
| post: pt.post, | post: pt.post, | ||||
| tag: pt.tag, | |||||
| tag: pt.tag.as_json(only: [:id, :category], methods: [:name]), | |||||
| user: pt.created_user && { id: pt.created_user.id, name: pt.created_user.name }, | user: pt.created_user && { id: pt.created_user.id, name: pt.created_user.name }, | ||||
| change_type: 'add', | change_type: 'add', | ||||
| timestamp: pt.created_at) | timestamp: pt.created_at) | ||||
| @@ -166,7 +166,7 @@ class PostsController < ApplicationController | |||||
| if pt.discarded_at | if pt.discarded_at | ||||
| events << Event.new( | events << Event.new( | ||||
| post: pt.post, | post: pt.post, | ||||
| tag: pt.tag, | |||||
| tag: pt.tag.as_json(only: [:id, :category], methods: [:name]), | |||||
| user: pt.deleted_user && { id: pt.deleted_user.id, name: pt.deleted_user.name }, | user: pt.deleted_user && { id: pt.deleted_user.id, name: pt.deleted_user.name }, | ||||
| change_type: 'remove', | change_type: 'remove', | ||||
| timestamp: pt.discarded_at) | timestamp: pt.discarded_at) | ||||
| @@ -9,7 +9,7 @@ class TagsController < ApplicationController | |||||
| Tag.all | Tag.all | ||||
| end | end | ||||
| render json: tags.includes(:tag_name) | |||||
| render json: tags.as_json(only: [:id, :category, :post_count], methods: [:name, :has_wiki]) | |||||
| end | end | ||||
| def autocomplete | def autocomplete | ||||
| @@ -21,12 +21,12 @@ class TagsController < ApplicationController | |||||
| 'nico', "nico:#{ q }%", "#{ q }%") | 'nico', "nico:#{ q }%", "#{ q }%") | ||||
| .order(Arel.sql('post_count DESC, tag_names.name ASC')) | .order(Arel.sql('post_count DESC, tag_names.name ASC')) | ||||
| .limit(20)) | .limit(20)) | ||||
| render json: tags | |||||
| render json: tags.as_json(only: [:id, :category, :post_count], methods: [:name, :has_wiki]) | |||||
| end | end | ||||
| def show | def show | ||||
| tag = Tag.find_by(id: params[:id]) | tag = Tag.find_by(id: params[:id]) | ||||
| render json: tag | |||||
| render json: tag.as_json(only: [:id, :category, :post_count], methods: [:name, :has_wiki]) | |||||
| end | end | ||||
| def show_by_name | def show_by_name | ||||
| @@ -35,7 +35,7 @@ class TagsController < ApplicationController | |||||
| tag = Tag.joins(:tag_name).includes(:tag_name).find_by(tag_names: { name: }) | tag = Tag.joins(:tag_name).includes(:tag_name).find_by(tag_names: { name: }) | ||||
| if tag | if tag | ||||
| render json: tag | |||||
| render json: tag.as_json(only: [:id, :category, :post_count], methods: [:name, :has_wiki]) | |||||
| else | else | ||||
| head :not_found | head :not_found | ||||
| end | end | ||||
| @@ -2,11 +2,13 @@ class WikiPagesController < ApplicationController | |||||
| rescue_from Wiki::Commit::Conflict, with: :render_wiki_conflict | rescue_from Wiki::Commit::Conflict, with: :render_wiki_conflict | ||||
| def index | def index | ||||
| render json: WikiPage.all | |||||
| pages = WikiPage.all | |||||
| render json: pages.as_json(methods: [:title]) | |||||
| end | end | ||||
| def show | def show | ||||
| render_wiki_page_or_404 WikiPage.includes(:tag_name).find_by(id: params[:id]) | |||||
| page = WikiPage.find_by(id: params[:id]) | |||||
| render_wiki_page_or_404 page | |||||
| end | end | ||||
| def show_by_title | def show_by_title | ||||
| @@ -86,7 +88,7 @@ class WikiPagesController < ApplicationController | |||||
| message = params[:message].presence | message = params[:message].presence | ||||
| Wiki::Commit.content!(page:, body:, created_user: current_user, message:) | Wiki::Commit.content!(page:, body:, created_user: current_user, message:) | ||||
| render json: page, status: :created | |||||
| render json: page.as_json(methods: [:title]), status: :created | |||||
| else | else | ||||
| render json: { errors: page.errors.full_messages }, | render json: { errors: page.errors.full_messages }, | ||||
| status: :unprocessable_entity | status: :unprocessable_entity | ||||
| @@ -127,7 +129,7 @@ class WikiPagesController < ApplicationController | |||||
| q = q.where('tag_names.name LIKE ?', "%#{ WikiPage.sanitize_sql_like(title) }%") | q = q.where('tag_names.name LIKE ?', "%#{ WikiPage.sanitize_sql_like(title) }%") | ||||
| end | end | ||||
| render json: q.limit(20) | |||||
| render json: q.limit(20).as_json(methods: [:title]) | |||||
| end | end | ||||
| def changes | def changes | ||||
| @@ -167,12 +169,14 @@ class WikiPagesController < ApplicationController | |||||
| pred = page.pred_revision_id(revision_id) | pred = page.pred_revision_id(revision_id) | ||||
| succ = page.succ_revision_id(revision_id) | succ = page.succ_revision_id(revision_id) | ||||
| return render json: page.as_json.merge(body:, revision_id:, pred:, succ:) | |||||
| return render json: page.as_json(methods: [:title]) | |||||
| .merge(body:, revision_id:, pred:, succ:) | |||||
| end | end | ||||
| rev = page.current_revision | rev = page.current_revision | ||||
| unless rev | unless rev | ||||
| return render json: page.as_json.merge(body: nil, revision_id: nil, pred: nil, succ: nil) | |||||
| return render json: page.as_json(methods: [:title]) | |||||
| .merge(body: nil, revision_id: nil, pred: nil, succ: nil) | |||||
| end | end | ||||
| if rev.redirect? | if rev.redirect? | ||||
| @@ -186,7 +190,7 @@ class WikiPagesController < ApplicationController | |||||
| pred = page.pred_revision_id(revision_id) | pred = page.pred_revision_id(revision_id) | ||||
| succ = page.succ_revision_id(revision_id) | succ = page.succ_revision_id(revision_id) | ||||
| render json: page.as_json.merge(body:, revision_id:, pred:, succ:) | |||||
| render json: page.as_json(methods: [:title]).merge(body:, revision_id:, pred:, succ:) | |||||
| end | end | ||||
| def render_wiki_conflict err | def render_wiki_conflict err | ||||
| @@ -22,7 +22,7 @@ class Tag < ApplicationRecord | |||||
| has_many :parents, through: :reversed_tag_implications, source: :parent_tag | has_many :parents, through: :reversed_tag_implications, source: :parent_tag | ||||
| belongs_to :tag_name | belongs_to :tag_name | ||||
| delegate :name, to: :tag_name | |||||
| delegate :name, to: :tag_name, allow_nil: true | |||||
| validates :tag_name, presence: true | validates :tag_name, presence: true | ||||
| enum :category, { deerjikist: 'deerjikist', | enum :category, { deerjikist: 'deerjikist', | ||||
| @@ -51,6 +51,10 @@ class Tag < ApplicationRecord | |||||
| (self.tag_name ||= build_tag_name).name = val | (self.tag_name ||= build_tag_name).name = val | ||||
| end | end | ||||
| def has_wiki | |||||
| tag_name&.wiki_page.present? | |||||
| end | |||||
| def self.tagme | def self.tagme | ||||
| @tagme ||= find_or_create_by_tag_name!('タグ希望', category: 'meta') | @tagme ||= find_or_create_by_tag_name!('タグ希望', category: 'meta') | ||||
| end | end | ||||
| @@ -107,8 +111,9 @@ class Tag < ApplicationRecord | |||||
| private | private | ||||
| def nico_tag_name_must_start_with_nico | def nico_tag_name_must_start_with_nico | ||||
| if ((category == 'nico' && !(name.start_with?('nico:'))) || | |||||
| (category != 'nico' && name.start_with?('nico:'))) | |||||
| n = name.to_s | |||||
| if ((category == 'nico' && !(n.start_with?('nico:'))) || | |||||
| (category != 'nico' && n.start_with?('nico:'))) | |||||
| errors.add :name, 'ニコニコ・タグの命名規則に反してゐます.' | errors.add :name, 'ニコニコ・タグの命名規則に反してゐます.' | ||||
| end | end | ||||
| end | end | ||||
| @@ -0,0 +1,9 @@ | |||||
| class DropTagAliases < ActiveRecord::Migration[7.0] | |||||
| def up | |||||
| drop_table :tag_aliases | |||||
| end | |||||
| def down | |||||
| raise ActiveRecord::IrreversibleMigration, '戻せません.' | |||||
| end | |||||
| end | |||||
| @@ -10,7 +10,7 @@ | |||||
| # | # | ||||
| # It's strongly recommended that you check this file into your version control system. | # It's strongly recommended that you check this file into your version control system. | ||||
| ActiveRecord::Schema[8.0].define(version: 2026_01_11_204400) do | |||||
| ActiveRecord::Schema[8.0].define(version: 2026_01_12_111800) do | |||||
| create_table "active_storage_attachments", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t| | create_table "active_storage_attachments", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t| | ||||
| t.string "name", null: false | t.string "name", null: false | ||||
| t.string "record_type", null: false | t.string "record_type", null: false | ||||
| @@ -106,14 +106,6 @@ ActiveRecord::Schema[8.0].define(version: 2026_01_11_204400) do | |||||
| t.index ["user_id"], name: "index_settings_on_user_id" | t.index ["user_id"], name: "index_settings_on_user_id" | ||||
| end | end | ||||
| create_table "tag_aliases", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t| | |||||
| t.bigint "tag_id", null: false | |||||
| t.string "name", null: false | |||||
| t.datetime "created_at", null: false | |||||
| t.datetime "updated_at", null: false | |||||
| t.index ["tag_id"], name: "index_tag_aliases_on_tag_id" | |||||
| end | |||||
| create_table "tag_implications", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t| | create_table "tag_implications", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t| | ||||
| t.bigint "tag_id", null: false | t.bigint "tag_id", null: false | ||||
| t.bigint "parent_tag_id", null: false | t.bigint "parent_tag_id", null: false | ||||
| @@ -239,7 +231,6 @@ ActiveRecord::Schema[8.0].define(version: 2026_01_11_204400) do | |||||
| add_foreign_key "posts", "posts", column: "parent_id" | add_foreign_key "posts", "posts", column: "parent_id" | ||||
| add_foreign_key "posts", "users", column: "uploaded_user_id" | add_foreign_key "posts", "users", column: "uploaded_user_id" | ||||
| add_foreign_key "settings", "users" | add_foreign_key "settings", "users" | ||||
| add_foreign_key "tag_aliases", "tags" | |||||
| add_foreign_key "tag_implications", "tags" | add_foreign_key "tag_implications", "tags" | ||||
| add_foreign_key "tag_implications", "tags", column: "parent_tag_id" | add_foreign_key "tag_implications", "tags", column: "parent_tag_id" | ||||
| add_foreign_key "tag_names", "tag_names", column: "canonical_id" | add_foreign_key "tag_names", "tag_names", column: "canonical_id" | ||||