diff --git a/backend/app/controllers/tags_controller.rb b/backend/app/controllers/tags_controller.rb index 475f84e..83e6c72 100644 --- a/backend/app/controllers/tags_controller.rb +++ b/backend/app/controllers/tags_controller.rb @@ -16,9 +16,12 @@ class TagsController < ApplicationController q = params[:q].to_s.strip return render json: [] if q.blank? + with_nico = !(params[:nico].to_s.strip.downcase.in?(['0', 'false', 'off', 'no'])) + tags = (Tag.joins(:tag_name).includes(:tag_name) - .where('(tags.category = ? AND tag_names.name LIKE ?) OR tag_names.name LIKE ?', - 'nico', "nico:#{ q }%", "#{ q }%") + .where(((with_nico ? '(tags.category = ? AND tag_names.name LIKE ?) OR ' : '') + + 'tag_names.name LIKE ?'), + *(with_nico ? ['nico', "nico:#{ q }%"] : []), "#{ q }%") .order(Arel.sql('post_count DESC, tag_names.name ASC')) .limit(20)) render json: tags.as_json(only: [:id, :category, :post_count], methods: [:name, :has_wiki]) diff --git a/backend/app/models/post.rb b/backend/app/models/post.rb index 1bd0723..18e873f 100644 --- a/backend/app/models/post.rb +++ b/backend/app/models/post.rb @@ -8,8 +8,10 @@ class Post < ApplicationRecord has_many :active_post_tags, -> { kept }, class_name: 'PostTag', inverse_of: :post has_many :post_tags_with_discarded, -> { with_discarded }, class_name: 'PostTag' has_many :tags, through: :active_post_tags + has_many :user_post_views, dependent: :destroy - has_many :post_similarities + has_many :post_similarities, dependent: :destroy + has_one_attached :thumbnail before_validation :normalise_url diff --git a/backend/app/models/tag.rb b/backend/app/models/tag.rb index 491a0e3..7952b58 100644 --- a/backend/app/models/tag.rb +++ b/backend/app/models/tag.rb @@ -3,53 +3,51 @@ class Tag < ApplicationRecord ; end - has_many :post_tags, dependent: :delete_all, inverse_of: :tag + has_many :post_tags, inverse_of: :tag has_many :active_post_tags, -> { kept }, class_name: 'PostTag', inverse_of: :tag has_many :post_tags_with_discarded, -> { with_discarded }, class_name: 'PostTag' has_many :posts, through: :active_post_tags - has_many :tag_aliases, dependent: :destroy has_many :nico_tag_relations, foreign_key: :nico_tag_id, dependent: :destroy has_many :linked_tags, through: :nico_tag_relations, source: :tag - has_many :reversed_nico_tag_relations, class_name: 'NicoTagRelation', - foreign_key: :tag_id, - dependent: :destroy + has_many :reversed_nico_tag_relations, + class_name: 'NicoTagRelation', foreign_key: :tag_id, dependent: :destroy has_many :linked_nico_tags, through: :reversed_nico_tag_relations, source: :nico_tag has_many :tag_implications, foreign_key: :parent_tag_id, dependent: :destroy has_many :children, through: :tag_implications, source: :tag - has_many :reversed_tag_implications, class_name: 'TagImplication', - foreign_key: :tag_id, - dependent: :destroy + has_many :reversed_tag_implications, + class_name: 'TagImplication', foreign_key: :tag_id, dependent: :destroy has_many :parents, through: :reversed_tag_implications, source: :parent_tag belongs_to :tag_name delegate :name, to: :tag_name, allow_nil: true validates :tag_name, presence: true - enum :category, { deerjikist: 'deerjikist', - meme: 'meme', - character: 'character', - general: 'general', - material: 'material', - nico: 'nico', - meta: 'meta' } + enum :category, deerjikist: 'deerjikist', + meme: 'meme', + character: 'character', + general: 'general', + material: 'material', + nico: 'nico', + meta: 'meta' validates :category, presence: true, inclusion: { in: Tag.categories.keys } validate :nico_tag_name_must_start_with_nico + validate :tag_name_must_be_canonical scope :nico_tags, -> { where(category: :nico) } CATEGORY_PREFIXES = { - 'gen:' => 'general', - 'djk:' => 'deerjikist', - 'meme:' => 'meme', - 'chr:' => 'character', - 'mtr:' => 'material', - 'meta:' => 'meta' }.freeze + 'gen:' => :general, + 'djk:' => :deerjikist, + 'meme:' => :meme, + 'chr:' => :character, + 'mtr:' => :material, + 'meta:' => :meta }.freeze def name= val (self.tag_name ||= build_tag_name).name = val @@ -60,11 +58,11 @@ class Tag < ApplicationRecord end def self.tagme - @tagme ||= find_or_create_by_tag_name!('タグ希望', category: 'meta') + @tagme ||= find_or_create_by_tag_name!('タグ希望', category: :meta) end def self.bot - @bot ||= find_or_create_by_tag_name!('bot操作', category: 'meta') + @bot ||= find_or_create_by_tag_name!('bot操作', category: :meta) end def self.normalise_tags tag_names, with_tagme: true, deny_nico: true @@ -75,7 +73,7 @@ class Tag < ApplicationRecord tags = tag_names.map do |name| pf, cat = CATEGORY_PREFIXES.find { |p, _| name.start_with?(p) } || ['', nil] name = name.delete_prefix(pf) - find_or_create_by_tag_name!(name, category: (cat || 'general')).tap do |tag| + find_or_create_by_tag_name!(name, category: (cat || :general)).tap do |tag| if cat && tag.category != cat tag.update!(category: cat) end @@ -127,4 +125,10 @@ class Tag < ApplicationRecord errors.add :name, 'ニコニコ・タグの命名規則に反してゐます.' end end + + def tag_name_must_be_canonical + if tag_name&.canonical_id + errors.add :tag_name, 'tag_names へは実体を示す必要があります.' + end + end end diff --git a/backend/app/models/tag_alias.rb b/backend/app/models/tag_alias.rb deleted file mode 100644 index f695886..0000000 --- a/backend/app/models/tag_alias.rb +++ /dev/null @@ -1,6 +0,0 @@ -class TagAlias < ApplicationRecord - belongs_to :tag - - validates :tag_id, presence: true - validates :name, presence: true, length: { maximum: 255 }, uniqueness: true -end diff --git a/backend/app/models/tag_name.rb b/backend/app/models/tag_name.rb index 2efd022..9276e56 100644 --- a/backend/app/models/tag_name.rb +++ b/backend/app/models/tag_name.rb @@ -6,4 +6,21 @@ class TagName < ApplicationRecord has_many :aliases, class_name: 'TagName', foreign_key: :canonical_id validates :name, presence: true, length: { maximum: 255 }, uniqueness: true + + validate :canonical_must_be_canonical + validate :alias_name_must_not_have_prefix + + private + + def canonical_must_be_canonical + if canonical&.canonical_id? + errors.add :canonical, 'canonical は実体を示す必要があります.' + end + end + + def alias_name_must_not_have_prefix + if canonical_id? && name.to_s.include?(':') + errors.add :name, 'エーリアス名にプレフィクスを含むことはできません.' + end + end end