From 749d49327e799e7818d3097863fc4d9131a877d2 Mon Sep 17 00:00:00 2001 From: miteruzo Date: Sun, 27 Sep 2026 23:55:19 +0900 Subject: [PATCH] #55 --- .../app/controllers/deerjikists_controller.rb | 2 +- .../controllers/gekanator_posts_controller.rb | 4 +- .../gekanator_questions_controller.rb | 4 +- .../app/controllers/materials_controller.rb | 30 ++-- .../app/controllers/nico_tags_controller.rb | 10 +- backend/app/controllers/posts_controller.rb | 40 +++--- .../controllers/tag_versions_controller.rb | 2 +- backend/app/controllers/tags_controller.rb | 134 +++++++++++------- .../theatre_skip_events_controller.rb | 4 +- backend/app/models/external_tag.rb | 8 +- backend/app/models/language.rb | 2 +- backend/app/models/locale.rb | 2 +- backend/app/models/post.rb | 18 +-- backend/app/models/tag.rb | 10 +- backend/app/models/tag_name.rb | 12 +- .../app/models/tag_name_sanitisation_rule.rb | 1 + .../app/representations/deerjikist_repr.rb | 3 +- backend/app/representations/material_repr.rb | 5 +- backend/app/representations/post_repr.rb | 2 +- backend/app/representations/tag_repr.rb | 15 +- .../app/services/material_version_recorder.rb | 2 +- backend/app/services/post_bulk_creator.rb | 2 +- backend/app/services/post_create_plan.rb | 41 +++--- backend/app/services/post_create_preflight.rb | 4 +- backend/app/services/post_creator.rb | 21 +-- backend/app/services/post_import_previewer.rb | 29 ++-- backend/app/services/post_metadata_fetcher.rb | 6 +- backend/app/services/tag_version_recorder.rb | 11 +- backend/app/services/tag_versioning.rb | 16 +-- backend/app/services/theatre_post_selector.rb | 6 +- 30 files changed, 258 insertions(+), 188 deletions(-) diff --git a/backend/app/controllers/deerjikists_controller.rb b/backend/app/controllers/deerjikists_controller.rb index 9302370..4d25cb6 100644 --- a/backend/app/controllers/deerjikists_controller.rb +++ b/backend/app/controllers/deerjikists_controller.rb @@ -7,7 +7,7 @@ class DeerjikistsController < ApplicationController deerjikist = Deerjikist .joins(:tag) - .includes(tag: :tag_name) + .includes(tag: :tag_names) .find_by(platform:, code:) if deerjikist render json: DeerjikistRepr.base(deerjikist) diff --git a/backend/app/controllers/gekanator_posts_controller.rb b/backend/app/controllers/gekanator_posts_controller.rb index a176354..b8be760 100644 --- a/backend/app/controllers/gekanator_posts_controller.rb +++ b/backend/app/controllers/gekanator_posts_controller.rb @@ -2,7 +2,7 @@ class GekanatorPostsController < ApplicationController def index posts = Post - .preload(:post_similarities, tags: :tag_name) + .preload(:post_similarities, tags: :tag_names) .with_attached_thumbnail .order(Arel.sql( 'COALESCE(posts.original_created_before - INTERVAL 1 MINUTE, ' \ @@ -56,7 +56,7 @@ class GekanatorPostsController < ApplicationController def tag_json tag { id: tag.id, - name: tag.name, + name: tag.name('ja'), category: tag.category } end diff --git a/backend/app/controllers/gekanator_questions_controller.rb b/backend/app/controllers/gekanator_questions_controller.rb index cc08a21..60e8725 100644 --- a/backend/app/controllers/gekanator_questions_controller.rb +++ b/backend/app/controllers/gekanator_questions_controller.rb @@ -126,9 +126,9 @@ class GekanatorQuestionsController < ApplicationController end Tag - .joins(:tag_name) + .joins(:tag_names) .where(category: categories.uniq) - .where(tag_names: { name: names.uniq }) + .where(tag_names: { language_code: 'ja', primary_flg: true, name: names.uniq }) .where.not(deprecated_at: nil) .pluck('tags.category', 'tag_names.name') .each_with_object({ }) do |(category, name), h| diff --git a/backend/app/controllers/materials_controller.rb b/backend/app/controllers/materials_controller.rb index 837cb84..5a04654 100644 --- a/backend/app/controllers/materials_controller.rb +++ b/backend/app/controllers/materials_controller.rb @@ -20,7 +20,7 @@ class MaterialsController < ApplicationController q = Material.includes(:material_export_items, thumbnail_attachment: :blob, file_attachment: :blob, - tag: :tag_name) + tag: :tag_names) q = q.where(tag_id: nil) if filters[:tag_state] == 'untagged' q = q.where.not(tag_id: nil) if filters[:tag_state] == 'tagged' q = apply_material_tag_filter(q, filters, tag_graph) @@ -63,7 +63,7 @@ class MaterialsController < ApplicationController .find_by(id: params[:id]) return head :not_found unless material - wiki_page_body = material.tag&.tag_name&.wiki_page&.current_revision&.body + wiki_page_body = material.tag&.tag_name('ja')&.wiki_page&.current_revision&.body render json: MaterialRepr.base(material, host: request.base_url).merge(wiki_page_body:) end @@ -96,7 +96,8 @@ class MaterialsController < ApplicationController updated_by_user: current_user) material.file.attach(uploaded_blob) if uploaded_blob material.save! - TagVersioning.record_tag_snapshot!(tag, created_by_user: current_user) + TagVersioning.record_tag_snapshot!(tag, created_by_user: current_user, + language_code: locale.language_code) upsert_export_paths!(material) MaterialVersionRecorder.record!(material:, event_type: :create, created_by_user: current_user) @@ -148,7 +149,8 @@ class MaterialsController < ApplicationController material.file.detach end material.save! - TagVersioning.record_tag_snapshot!(tag, created_by_user: current_user) + TagVersioning.record_tag_snapshot!(tag, created_by_user: current_user, + language_code: locale.language_code) upsert_export_paths!(material) MaterialVersionRecorder.record!(material:, event_type: :update, created_by_user: current_user) @@ -254,7 +256,12 @@ class MaterialsController < ApplicationController end def material_index_join_tag_name q - q.left_joins(tag: :tag_name) + q.left_joins(:tag).joins(<<~SQL.squish) + LEFT JOIN tag_names + ON tag_names.tag_id = tags.id + AND tag_names.language_code = 'ja' + AND tag_names.primary_flg = TRUE + SQL end def material_index_join_file_blob q @@ -270,9 +277,11 @@ class MaterialsController < ApplicationController def apply_material_query q, term like = "%#{ ActiveRecord::Base.sanitize_sql_like(term) }%" - q.where('tag_names.name LIKE :q OR materials.url LIKE :q OR ' \ - 'material_file_blobs.filename LIKE :q', - q: like) + q.where(<<~SQL.squish, q: like) + tag_names.name LIKE :q + OR materials.url LIKE :q + OR material_file_blobs.filename LIKE :q + SQL end def apply_material_media_kind q, media_kind @@ -324,8 +333,9 @@ class MaterialsController < ApplicationController end tags_by_id = Tag - .joins(:tag_name) - .where(id: scope_tag_ids) + .joins(:tag_names) + .where(id: scope_tag_ids, + tag_names: { language_code: 'ja', primary_flg: true }) .pluck('tags.id', 'tag_names.name', 'tags.category', 'tags.deprecated_at') .each_with_object({ }) do |(id, name, category, deprecated_at), hash| hash[id] = { id:, name:, category:, deprecated: deprecated_at.present? } diff --git a/backend/app/controllers/nico_tags_controller.rb b/backend/app/controllers/nico_tags_controller.rb index 4f8275c..03f17f2 100644 --- a/backend/app/controllers/nico_tags_controller.rb +++ b/backend/app/controllers/nico_tags_controller.rb @@ -24,7 +24,7 @@ class NicoTagsController < ApplicationController ExternalTag .joins("LEFT JOIN (#{ post_tag_max_sql }) post_tag_max " \ 'ON post_tag_max.external_tag_id = external_tags.id') - .includes(linked_tags: { tag_name: :wiki_page }) + .includes(linked_tags: { tag_names: :wiki_page }) if name q = q.where(('external_tags.name LIKE ? ' + "OR CONCAT(external_tags.platform, ':', external_tags.name) LIKE ?"), @@ -34,7 +34,8 @@ class NicoTagsController < ApplicationController if linked_tag linked_tag_ids = Tag - .joins(:tag_name) + .joins(:tag_names) + .where(tag_names: { language_code: 'ja', primary_flg: true }) .where('tag_names.name LIKE ?', "%#{ linked_tag }%") .pluck(:id) linked_nico_tag_ids = NicoTagRelation.where(tag_id: linked_tag_ids).pluck(:nico_tag_id) @@ -95,7 +96,10 @@ class NicoTagsController < ApplicationController with_tagme: false, with_no_deerjikist: false) - TagVersioning.record_tag_snapshots!(linked_tags, created_by_user: current_user) + TagVersioning.record_tag_snapshots!( + linked_tags, + created_by_user: current_user, + language_code: locale.language_code) tag.linked_tags = linked_tags tag.save! diff --git a/backend/app/controllers/posts_controller.rb b/backend/app/controllers/posts_controller.rb index 6b1c633..d88271b 100644 --- a/backend/app/controllers/posts_controller.rb +++ b/backend/app/controllers/posts_controller.rb @@ -53,7 +53,7 @@ class PostsController < ApplicationController .reselect('posts.*', Arel.sql("#{ updated_at_all_sql } AS updated_at_all")) .preload(:external_tags, :uploaded_user, :parents, :children, post_tags: [:sections, { tag: [:deerjikists, :materials, - { tag_name: :wiki_page }] }]) + { tag_names: :wiki_page }] }]) .with_attached_thumbnail q = q.where('posts.url LIKE ?', "%#{ url }%") if url @@ -110,7 +110,7 @@ class PostsController < ApplicationController filtered_posts(locale) .preload(:uploaded_user, :parents, :children, post_tags: [:sections, { tag: [:deerjikists, :materials, - { tag_name: :wiki_page }] }]) + { tag_names: :wiki_page }] }]) .with_attached_thumbnail .order('RAND()') .first @@ -195,7 +195,7 @@ class PostsController < ApplicationController Post .includes(:uploaded_user, :parents, :children, post_tags: [:sections, { tag: [:deerjikists, :materials, - { tag_name: :wiki_page }] }]) + { tag_names: :wiki_page }] }]) .with_attached_thumbnail .find_by(id: params[:id]) return head :not_found unless post @@ -341,7 +341,7 @@ class PostsController < ApplicationController base_version = post.post_versions.find_by!(version_no: base_version_no) base_snapshot = post_snapshot_from_version(base_version) - current_snapshot = post_snapshot_from_record(post) + current_snapshot = post_snapshot_from_record(post, locale) end incoming_snapshot = post_incoming_snapshot(locale:, title:, @@ -418,11 +418,11 @@ class PostsController < ApplicationController if match_type == 'any' literals.reduce(Post.none) do |posts, literal| - posts.or(tag_literal_relation(literal[:name], negative: literal[:negative])) + posts.or(tag_literal_relation(locale, literal[:name], negative: literal[:negative])) end else literals.reduce(Post.all) do |posts, literal| - ids = tagged_post_ids_for(literal[:name]) + ids = tagged_post_ids_for(locale, literal[:name]) if literal[:negative] posts.where.not(id: ids) else @@ -432,8 +432,8 @@ class PostsController < ApplicationController end end - def tag_literal_relation name, negative: - ids = tagged_post_ids_for(name) + def tag_literal_relation locale, name, negative: + ids = tagged_post_ids_for(locale, name) if negative Post.where.not(id: ids) else @@ -441,11 +441,11 @@ class PostsController < ApplicationController end end - def tagged_post_ids_for(name) + def tagged_post_ids_for locale, name posts_by_internal_tags = Post - .joins(tags: :tag_name) - .where(tag_names: { name: }) + .joins(tags: :tag_names) + .where(tag_names: { language_code: locale.language_code, name: }) .select(:id) posts_by_external_tags = @@ -688,24 +688,25 @@ class PostsController < ApplicationController .sort end - def post_snapshot_from_record post + def post_snapshot_from_record post, locale { title: post.title, video_ms: post.video_ms, original_created_from: snapshot_time(post.original_created_from), original_created_before: snapshot_time(post.original_created_before), - tag_names: editable_tag_names_from_post(post), + tag_names: editable_tag_names_from_post(post, locale.language_code), parent_post_ids: post.parent_posts.order(:id).pluck(:id) } end - def editable_tag_names_from_post post + def editable_tag_names_from_post post, language_code post .post_tags - .joins(tag: :tag_name) + .joins(tag: :tag_names) .merge(Tag.where(deprecated_at: nil)) - .includes(:sections, tag: :tag_name) + .where(tag_names: { language_code:, primary_flg: true }) + .includes(:sections, tag: :tag_names) .order('tag_names.name') .map do |post_tag| - name = post_tag.tag.tag_name.name + name = post_tag.tag.name(language_code) sections = post_tag.sections.sort_by(&:begin_ms) next name if sections.empty? @@ -732,7 +733,7 @@ class PostsController < ApplicationController original_created_from: snapshot_time(original_created_from), original_created_before: snapshot_time(original_created_before), tag_names: tags.uniq(&:id).map { |tag| - "#{ tag.name }#{ sections[tag.id].to_a.map { section_literal(_1) }.join }" + "#{ tag.name(locale.language_code) }#{ sections[tag.id].to_a.map { section_literal(_1) }.join }" }.sort, parent_post_ids: parent_post_ids.sort } end @@ -868,7 +869,8 @@ class PostsController < ApplicationController with_tagme: false, deny_deprecated: true, with_sections: true) => { tags:, sections: } - TagVersioning.record_tag_snapshots!(tags, created_by_user: current_user) + TagVersioning.record_tag_snapshots!(tags, created_by_user: current_user, + language_code: locale.language_code) tags = Tag.expand_parent_tags(tags).reject(&:deprecated?) diff --git a/backend/app/controllers/tag_versions_controller.rb b/backend/app/controllers/tag_versions_controller.rb index 243a548..b861cfe 100644 --- a/backend/app/controllers/tag_versions_controller.rb +++ b/backend/app/controllers/tag_versions_controller.rb @@ -47,7 +47,7 @@ class TagVersionsController < ApplicationController tags_by_id = Tag - .includes(:tag_name, :materials, { tag_name: :wiki_page }) + .includes(:tag_names, :materials, tag_names: :wiki_page) .where(id: all_parent_tag_ids) .index_by(&:id) diff --git a/backend/app/controllers/tags_controller.rb b/backend/app/controllers/tags_controller.rb index b1057c2..643a548 100644 --- a/backend/app/controllers/tags_controller.rb +++ b/backend/app/controllers/tags_controller.rb @@ -176,7 +176,7 @@ class TagsController < ApplicationController Tag .joins(:tag_names) .includes(:tag_names, :materials, tag_names: :wiki_page) - .where(tag_names: { language_code: locale.language.code, primary_flg: true }, + .where(tag_names: { language_code: locale.language_code, primary_flg: true }, id: tag_ids) .index_by(&:id) external_tags_by_id = @@ -186,7 +186,7 @@ class TagsController < ApplicationController render json: { tags: rows.map { |row| if row['source'] == 'tag' - TagRepr.base(tags_by_id.fetch(row['id'])) + TagRepr.base(tags_by_id.fetch(row['id']), language_code: locale.language_code) else external_tag_json(external_tags_by_id.fetch(row['id'])) end @@ -223,15 +223,15 @@ class TagsController < ApplicationController alias_rows = TagName - .where(language_code: locale.language_code, primary_code: false) + .where(language_code: locale.language_code, primary_flg: false) .where('name LIKE ?', prefix) .pluck(:tag_id, :name) - matched_alias_by_tag_name_id = { } + matched_alias_by_tag_id = { } tag_ids = [] alias_rows.each do |tag_id, alias_name| tag_ids << tag_id - matched_alias_by_tag_name_id[tag_id] ||= alias_name + matched_alias_by_tag_id[tag_id] ||= alias_name end base = @@ -251,7 +251,8 @@ class TagsController < ApplicationController .order(Arel.sql('tags.post_count DESC, tag_names.name')) .limit(20) .map { |tag| - TagRepr.base(tag).merge(matched_alias: matched_alias_by_tag_name_id[tag.tag_name_id]) + TagRepr.base(tag, language_code: locale.language_code) + .merge(matched_alias: matched_alias_by_tag_id[tag.id]) } return render json: internal_rows unless with_nico @@ -267,8 +268,8 @@ class TagsController < ApplicationController .map { external_tag_json(_1) } rows = - (internal_rows + external_rows) - .sort_by { |row| [-row['post_count'], row['name']] } + (internal_rows + external_rows) + .sort_by { |row| [-row['post_count'], row['name'] || row[:name]] } .first(20) render json: rows @@ -283,7 +284,7 @@ class TagsController < ApplicationController .includes(:tag_names, :materials, tag_names: :wiki_page) .find_by(id: params[:id], tag_names: { language_code: locale.language_code, primary_flg: true }) - return render json: TagRepr.base(tag) if tag + return render json: TagRepr.base(tag, language_code: locale.language_code) if tag external_tag = ExternalTag.find_by(id: params[:id]) return render json: ExternalTagRepr.base(external_tag) if external_tag @@ -302,7 +303,7 @@ class TagsController < ApplicationController .joins(:tag_names) .includes(:tag_names, :materials, tag_names: :wiki_page) .find_by(tag_names: { name:, language_code: locale.language_code, primary_flg: true }) - return render json: TagRepr.base(tag) if tag + return render json: TagRepr.base(tag, language_code: locale.language_code) if tag platform, external_name = name.split(':', 2) return head :not_found unless external_name @@ -323,7 +324,7 @@ class TagsController < ApplicationController tag_names: { language_code: locale.language_code, primary_flg: true }) return head :not_found unless tag - render json: { tag: TagRepr.base(tag), + render json: { tag: TagRepr.base(tag, language_code: locale.language_code), deerjikists: DeerjikistRepr.many(tag.deerjikists) } end @@ -340,7 +341,7 @@ class TagsController < ApplicationController .find_by(tag_names: { name:, language_code: locale.language_code, primary_flg: true }) return head :not_found unless tag - render json: { tag: TagRepr.base(tag), + render json: { tag: TagRepr.base(tag, language_code: locale.language_code), deerjikists: DeerjikistRepr.many(tag.deerjikists) } end @@ -348,6 +349,8 @@ class TagsController < ApplicationController return head :unauthorized unless current_user return head :forbidden unless current_user.gte_member? + locale = resolve_locale! + tag = Tag .joins(:tag_names) @@ -359,8 +362,6 @@ class TagsController < ApplicationController rows = normalise_deerjikist_rows(tag) return if performed? - locale = resolve_locale! - ApplicationRecord.transaction do tag.lock! @@ -423,7 +424,7 @@ class TagsController < ApplicationController graph = build_with_depth_graph(material_filter) - render json: build_tag_children(tag, graph:) + render json: build_tag_children(tag, graph:, language_code: locale.language_code) end def update_all @@ -452,11 +453,12 @@ class TagsController < ApplicationController end ApplicationRecord.transaction do - TagVersioning.ensure_snapshot!(tag, created_by_user: current_user) + TagVersioning.ensure_snapshot!(tag, created_by_user: current_user, + language_code: locale.language_code) - old_name = tag.name + old_name = tag.name(locale.language_code) name_changed = name != old_name - wiki_page = tag.tag_name.wiki_page if name_changed + wiki_page = tag.tag_name(locale.language_code)&.wiki_page if name_changed if tag.deprecated? == deprecated tag.update!(category:) @@ -468,7 +470,7 @@ class TagsController < ApplicationController alias_names << old_name if name_changed alias_names.delete(name) - update_aliases!(tag, alias_names) + update_aliases!(locale, tag, alias_names) update_parent_tags!(locale, tag, parent_names) tag.reload @@ -477,11 +479,12 @@ class TagsController < ApplicationController tag, event_type: :update, created_by_user: current_user, + language_code: locale.language_code, name_changed:, wiki_page:) end - render json: TagRepr.base(tag.reload) + render json: TagRepr.base(tag.reload, language_code: locale.language_code) end def update @@ -504,13 +507,14 @@ class TagsController < ApplicationController end ApplicationRecord.transaction do - TagVersioning.ensure_snapshot!(tag, created_by_user: current_user) + TagVersioning.ensure_snapshot!(tag, created_by_user: current_user, + language_code: locale.language_code) - old_name = tag.name + old_name = tag.name(locale.language_code) name_changed = name.present? && name != old_name - wiki_page = tag.tag_name.wiki_page if name_changed + wiki_page = tag.tag_name(locale.language_code)&.wiki_page if name_changed - rename_tag_name!(tag, name) if name_changed + rename_tag_name!(locale, tag, name) if name_changed tag.update!(category:) if category.present? if deprecated_given && tag.deprecated? != deprecated tag.update!(deprecated_at: deprecated ? Time.current : nil) @@ -522,11 +526,12 @@ class TagsController < ApplicationController tag, event_type: :update, created_by_user: current_user, + language_code: locale.language_code, name_changed:, wiki_page:) end - render json: TagRepr.base(tag.reload) + render json: TagRepr.base(tag.reload, language_code: locale.language_code) end private @@ -693,29 +698,30 @@ class TagsController < ApplicationController children: [] } end - def build_tag_children tag, graph: nil + def build_tag_children tag, graph: nil, language_code: 'ja' material = tag.materials.first tag_graph = graph && graph[:tags_by_id][tag.id] material = nil if tag_graph && !with_depth_visible_tag?(tag_graph, graph[:material_filter]) - children = tag.children.sort_by(&:name) + children = tag.children.sort_by { _1.name(language_code) } if graph children = children.filter { |child_tag| visible_subtree?(child_tag.id, graph) } end - TagRepr.base(tag).merge( - children: children.map { build_tag_children(_1, graph:) }, + TagRepr.base(tag, language_code:).merge( + children: children.map { build_tag_children(_1, graph:, language_code:) }, has_material: tag_graph ? tag_graph[:has_material] : material.present?, material: material && MaterialRepr.base(material, host: request.base_url)) end - def record_tag_version! tag, event_type:, created_by_user:, name_changed: false, wiki_page: nil - TagVersionRecorder.record!(tag:, event_type:, created_by_user:) + def record_tag_version! tag, event_type:, created_by_user:, language_code: 'ja', + name_changed: false, wiki_page: nil + TagVersionRecorder.record!(tag:, event_type:, created_by_user:, language_code:) return unless name_changed - wiki_page ||= tag.tag_name.wiki_page + wiki_page ||= tag.tag_name('ja')&.wiki_page return unless wiki_page&.wiki_versions&.exists? WikiVersionRecorder.record!( @@ -725,9 +731,13 @@ class TagsController < ApplicationController end def validate_tag_rename locale, tag, name - return true if name.blank? || name == tag.name + return true if name.blank? || name == tag.name(locale.language_code) - if tag.in?([Tag.tagme, Tag.bot, Tag.no_deerjikist, Tag.video, Tag.niconico]) + system_tag_names = ['タグ希望', 'bot操作', 'ニジラー情報不詳', '動画', 'ニコニコ'] + if TagName.exists?(tag_id: tag.id, + language_code: 'ja', + primary_flg: true, + name: system_tag_names) render_unprocessable_entity 'システム・タグの名称は変更できません.', field: :name return false end @@ -746,7 +756,16 @@ class TagsController < ApplicationController target_tag_name = TagName.find_by(language_code: locale.language_code, name:) unless target_tag_name - current_tag_name.update!(name:) + if current_tag_name + current_tag_name.update!(name:) + else + current_tag_name = TagName.create!( + tag:, + language_code: locale.language_code, + script_code: locale.script_code, + name:, + primary_flg: true) + end return end @@ -754,68 +773,79 @@ class TagsController < ApplicationController end def promote_tag_alias! tag, current_tag_name:, promoted_tag_name: - old_owner_tag = promoted_tag_name.canonical&.tag + old_owner_tag = promoted_tag_name.tag if old_owner_tag && old_owner_tag != tag TagVersioning.ensure_snapshot!(old_owner_tag, created_by_user: current_user) end - promoted_tag_name.update!(canonical_id: nil, primary_flg: true) + current_tag_name.update!(canonical_id: promoted_tag_name.id, primary_flg: false) + promoted_tag_name.update!(tag:, canonical_id: nil, primary_flg: true) TagName.where(tag:, - language_code: current_tag_name.language.language_code, + language_code: current_tag_name.language_code, primary_flg: false) .where.not(id: promoted_tag_name.id) .find_each do |alias_tag_name| - alias_tag_name.update!(canonical_id: promoted_tag_name, primary_flg: false) + alias_tag_name.update!(canonical_id: promoted_tag_name.id, primary_flg: false) end current_tag_name.wiki_page&.update!(tag_name_id: promoted_tag_name.id) tag.update!(tag_name_id: promoted_tag_name.id) current_tag_name.association(:wiki_page).reset current_tag_name.association(:tag).reset - current_tag_name.reload.update!(canonical_id: promoted_tag_name, primary_flg: false) + current_tag_name.reload.update!(canonical_id: promoted_tag_name.id, primary_flg: false) return unless old_owner_tag && old_owner_tag != tag - record_tag_version!(old_owner_tag.reload, event_type: :update, created_by_user: current_user) + record_tag_version!(old_owner_tag.reload, event_type: :update, + created_by_user: current_user, + language_code: current_tag_name.language_code) end - def update_aliases! tag, alias_names + def update_aliases! locale, tag, alias_names alias_names = alias_names.uniq affected_tags = [tag] - current_aliases = tag.tag_name.aliases.to_a + primary_tag_name = tag.tag_name(locale.language_code) + current_aliases = tag.tag_names.where(language_code: locale.language_code, + primary_flg: false).to_a current_aliases.each do |alias_tag_name| next if alias_names.include?(alias_tag_name.name) - affected_tags << alias_tag_name.canonical&.tag + affected_tags << alias_tag_name.tag end alias_names.each do |alias_name| - alias_tag_name = TagName.find_or_create_by!(name: alias_name) - affected_tags << alias_tag_name.canonical&.tag + alias_tag_name = TagName.find_by(language_code: locale.language_code, name: alias_name) + affected_tags << alias_tag_name&.tag end affected_tags.compact.uniq.each do |affected_tag| - TagVersioning.ensure_snapshot!(affected_tag, created_by_user: current_user) + TagVersioning.ensure_snapshot!(affected_tag, created_by_user: current_user, + language_code: locale.language_code) end current_aliases.each do |alias_tag_name| next if alias_names.include?(alias_tag_name.name) - alias_tag_name.update!(canonical_id: nil) + alias_tag_name.update!(canonical_id: nil, tag_id: nil) end alias_names.each do |alias_name| - alias_tag_name = TagName.find_or_create_by!(name: alias_name) - alias_tag_name.update!(canonical_id: tag.tag_name.id) + alias_tag_name = TagName.find_or_initialize_by( + language_code: locale.language_code, + name: alias_name) + alias_tag_name.script_code = locale.script_code + alias_tag_name.update!(tag:, primary_flg: false, canonical_id: primary_tag_name.id) end affected_tags.compact.uniq.each do |affected_tag| - record_tag_version!(affected_tag, event_type: :update, created_by_user: current_user) + record_tag_version!(affected_tag, event_type: :update, + created_by_user: current_user, + language_code: locale.language_code) end end @@ -899,8 +929,6 @@ class TagsController < ApplicationController conflicts = deerjikists.filter { |deerjikist| deerjikist.tag_id != tag.id } return if conflicts.empty? - locale = resolve_locale! - tag_names_by_id = Tag .joins(:tag_names) diff --git a/backend/app/controllers/theatre_skip_events_controller.rb b/backend/app/controllers/theatre_skip_events_controller.rb index fbbdae9..c5047c5 100644 --- a/backend/app/controllers/theatre_skip_events_controller.rb +++ b/backend/app/controllers/theatre_skip_events_controller.rb @@ -6,7 +6,7 @@ class TheatreSkipEventsController < ApplicationController events = TheatreSkipEvent .where(theatre_id: params[:theatre_id]) - .includes(:post, tags: :tag_name) + .includes(:post, tags: :tag_names) .order(created_at: :desc) .limit(limit) @@ -14,7 +14,7 @@ class TheatreSkipEventsController < ApplicationController { id: event.id, theatre_id: event.theatre_id, post: { id: event.post.id, title: event.post.title, url: event.post.url }, - tags: event.tags.map { |tag| { id: tag.id, name: tag.name } }, + tags: event.tags.map { |tag| { id: tag.id, name: tag.name('ja') } }, programme_position: event.programme_position, created_at: event.created_at } } diff --git a/backend/app/models/external_tag.rb b/backend/app/models/external_tag.rb index f49ec54..dc81bef 100644 --- a/backend/app/models/external_tag.rb +++ b/backend/app/models/external_tag.rb @@ -14,7 +14,11 @@ class ExternalTag < ApplicationRecord has_many :linked_tags, through: :nico_tag_relations, source: :tag - def snapshot_linked_tag_names - linked_tags.joins(:tag_name).order('tag_names.name').pluck('tag_names.name') + def snapshot_linked_tag_names language_code = 'ja' + linked_tags + .joins(:tag_names) + .where(tag_names: { language_code:, primary_flg: true }) + .order('tag_names.name') + .pluck('tag_names.name') end end diff --git a/backend/app/models/language.rb b/backend/app/models/language.rb index cd37ec3..1572f28 100644 --- a/backend/app/models/language.rb +++ b/backend/app/models/language.rb @@ -1,3 +1,3 @@ class Language < ApplicationRecord - has_many :languages, class_name: 'Locale', foreign_key: :language_code + has_many :locales, foreign_key: :language_code, primary_key: :code end diff --git a/backend/app/models/locale.rb b/backend/app/models/locale.rb index afb7e17..a2081f6 100644 --- a/backend/app/models/locale.rb +++ b/backend/app/models/locale.rb @@ -13,7 +13,7 @@ class Locale < ApplicationRecord Tag.where.not(id: tag_ids).find_each do TagName.create!(tag_id: _1.id, language_code:, - name: TagName.generate_name!(self, _1, _1.name(language_code)), + name: TagName.generate_name(self, _1, _1.name('ja')), script_code:, primary_flg: true, # TODO: 公証実装したら書く. diff --git a/backend/app/models/post.rb b/backend/app/models/post.rb index 805e91d..6db6ca8 100644 --- a/backend/app/models/post.rb +++ b/backend/app/models/post.rb @@ -126,13 +126,14 @@ class Post < ApplicationRecord super(options).merge(thumbnail: nil) end - def snapshot_tag_names + def snapshot_tag_names language_code = 'ja' post_tags - .joins(tag: :tag_name) - .includes(:sections, tag: :tag_name) + .joins(tag: :tag_names) + .where(tag_names: { language_code:, primary_flg: true }) + .includes(:sections, tag: :tag_names) .order('tag_names.name') .map do |post_tag| - name = post_tag.tag.tag_name.name + name = post_tag.tag.name(language_code) sections = post_tag.sections.sort_by(&:begin_ms) next name if sections.empty? @@ -152,16 +153,17 @@ class Post < ApplicationRecord "#{ tag.fetch('name') }#{ sections.join }" end - def snapshot_tags_json + def snapshot_tags_json language_code = 'ja' tag_snapshots = post_tags - .joins(tag: :tag_name) - .includes(:sections, tag: :tag_name) + .joins(tag: :tag_names) + .where(tag_names: { language_code:, primary_flg: true }) + .includes(:sections, tag: :tag_names) .order('tags.id') .map { |pt| { 'tag_id' => pt.tag.id, 'version_no' => pt.tag.version_no, - 'name' => pt.tag.name, + 'name' => pt.tag.name(language_code), 'category' => pt.tag.category, 'sections' => pt.sections.sort_by(&:begin_ms).map { { 'begin_ms' => _1.begin_ms, 'end_ms' => _1.end_ms } diff --git a/backend/app/models/tag.rb b/backend/app/models/tag.rb index 9add0ca..e449781 100644 --- a/backend/app/models/tag.rb +++ b/backend/app/models/tag.rb @@ -79,7 +79,7 @@ class Tag < ApplicationRecord def tag_name(language_code) = tag_names.find_by(language_code:, primary_flg: true) def name(language_code) = tag_name(language_code)&.name - def wiki_page = WikiPage.find_by(tag_name_id: id) + def wiki_page = tag_name('ja')&.wiki_page def deprecated? = deprecated_at? @@ -132,7 +132,7 @@ class Tag < ApplicationRecord find_or_create_by_tag_name!(locale, name, category: (cat || :general)).tap do |tag| if deny_deprecated && tag.deprecated? - raise DeprecatedTagNormalisationError, [tag.name] + raise DeprecatedTagNormalisationError, [tag.name(locale.language_code)] end tag.update!(category: cat) if cat && tag.category != cat @@ -262,7 +262,7 @@ class Tag < ApplicationRecord end end - source_tag_name = source_tag.tag_name + source_tag_name = source_tag.tag_name('ja') if source_tag_name.wiki_page.present? raise ActiveRecord::RecordInvalid.new(source_tag_name) @@ -291,7 +291,9 @@ class Tag < ApplicationRecord target_tag.reload end - def snapshot_aliases(language_code) = tag_name(language_code).aliases.order(:name).pluck(:name) + def snapshot_aliases(language_code) + tag_names.where(language_code:, primary_flg: false).order(:name).pluck(:name) + end def snapshot_parent_tag_ids = parents.order(:id).pluck(:id) diff --git a/backend/app/models/tag_name.rb b/backend/app/models/tag_name.rb index 80a51cb..5d47460 100644 --- a/backend/app/models/tag_name.rb +++ b/backend/app/models/tag_name.rb @@ -14,9 +14,6 @@ class TagName < ApplicationRecord def primary? = primary_flg - def canonical = TagName.find_by(language_code:, tag_id:, primary_flg: true) - def aliases = TagName.where(language_code:, tag_id:, primary_flg: false) - def self.canonicalise locale, names names = Array(names).map { |n| n.to_s.strip }.reject(&:blank?) return [] if names.blank? @@ -24,17 +21,18 @@ class TagName < ApplicationRecord tns = TagName.where(language_code: locale.language_code, name: names).index_by(&:name) names.map { |name| - if !(tns[name]) || tns[name].primary? + tag_name = tns[name] + if !tag_name || tag_name.primary? name else TagName.find_by(language_code: locale.language_code, - tag_id: tns[name].tag_id, - primary_flg: true).name + tag_id: tag_name.tag_id, + primary_flg: true)&.name || name end }.uniq end - def self.generate_name! locale, tag, name + def self.generate_name locale, tag, name # TODO: 言語ごとの自動命名ロジック完成したら書く. "Tag_##{ tag.id }" diff --git a/backend/app/models/tag_name_sanitisation_rule.rb b/backend/app/models/tag_name_sanitisation_rule.rb index 1086bbb..4731d4f 100644 --- a/backend/app/models/tag_name_sanitisation_rule.rb +++ b/backend/app/models/tag_name_sanitisation_rule.rb @@ -36,6 +36,7 @@ class TagNameSanitisationRule < ApplicationRecord if existing_tag Tag.merge_tags!(existing_tag, source_tag) if tn.tag elsif source_tag + tn.update_columns(tag_id: nil, updated_at: Time.current) source_tag.update_columns(tag_name_id: existing_tn.id, updated_at: Time.current) existing_tn.update_columns(tag_id: source_tag.id, updated_at: Time.current) end diff --git a/backend/app/representations/deerjikist_repr.rb b/backend/app/representations/deerjikist_repr.rb index fbb73c9..552e350 100644 --- a/backend/app/representations/deerjikist_repr.rb +++ b/backend/app/representations/deerjikist_repr.rb @@ -7,7 +7,8 @@ module DeerjikistRepr module_function def base deerjikist - deerjikist.as_json(BASE) + deerjikist.as_json(BASE).merge( + tag: deerjikist.tag && TagRepr.base(deerjikist.tag, language_code: 'ja')) end def many deerjikists diff --git a/backend/app/representations/material_repr.rb b/backend/app/representations/material_repr.rb index 30d21f9..4893dbd 100644 --- a/backend/app/representations/material_repr.rb +++ b/backend/app/representations/material_repr.rb @@ -14,6 +14,7 @@ module MaterialRepr def base material, host: material.as_json(BASE).merge( + tag: material.tag && TagRepr.base(material.tag, language_code: 'ja'), file: if material.file.attached? Rails.application.routes.url_helpers.rails_storage_proxy_url( material.file, host:) @@ -80,7 +81,7 @@ module MaterialRepr end def thumbnail_fallback_text material - material.tag&.name || material.created_at&.strftime('%Y-%m-%d') + material.tag&.name('ja') || material.created_at&.strftime('%Y-%m-%d') end def thumbnail_fallback_kind material @@ -102,7 +103,7 @@ module MaterialRepr return nil unless tag { id: tag.id, - name: tag.name, + name: tag.name('ja'), category: tag.category, deprecated_at: tag.deprecated_at } end diff --git a/backend/app/representations/post_repr.rb b/backend/app/representations/post_repr.rb index 01206e4..fce7ccf 100644 --- a/backend/app/representations/post_repr.rb +++ b/backend/app/representations/post_repr.rb @@ -91,7 +91,7 @@ module PostRepr post .post_tags .reject { _1.tag.deprecated? } - .sort_by { _1.tag.name } + .sort_by { _1.tag.name('ja') } .map { |post_tag| TagRepr.inline(post_tag.tag).merge( 'children' => [], diff --git a/backend/app/representations/tag_repr.rb b/backend/app/representations/tag_repr.rb index 3958953..d54e743 100644 --- a/backend/app/representations/tag_repr.rb +++ b/backend/app/representations/tag_repr.rb @@ -3,18 +3,19 @@ module TagRepr BASE = { only: [:id, :category, :post_count, :created_at, :updated_at, :deprecated_at], - methods: [:name, :has_wiki, :material_id, :has_deerjikists] }.freeze + methods: [:has_wiki, :material_id, :has_deerjikists] }.freeze module_function - def base tag - tag.as_json(BASE).merge(aliases: tag.snapshot_aliases, - parents: tag.parents.map { _1.as_json(BASE) }) + def base tag, language_code: 'ja' + tag.as_json(BASE).merge(name: tag.name(language_code), + aliases: tag.snapshot_aliases(language_code), + parents: tag.parents.map { inline(_1, language_code:) }) end - def inline tag - tag.as_json(BASE).merge(aliases: [], parents: []) + def inline tag, language_code: 'ja' + tag.as_json(BASE).merge(name: tag.name(language_code), aliases: [], parents: []) end - def many(tags) = tags.map { |t| base(t) } + def many(tags, language_code: 'ja') = tags.map { |tag| base(tag, language_code:) } end diff --git a/backend/app/services/material_version_recorder.rb b/backend/app/services/material_version_recorder.rb index 8f268f7..08d5ad1 100644 --- a/backend/app/services/material_version_recorder.rb +++ b/backend/app/services/material_version_recorder.rb @@ -31,7 +31,7 @@ class MaterialVersionRecorder < VersionRecorder { url: @record.url, parent: @record.parent, tag: @record.tag, - tag_name: @record.tag&.name, + tag_name: @record.tag&.name('ja'), tag_category: @record.tag&.category, source_kind: @record.source_kind, source_uri: @record.source_uri, diff --git a/backend/app/services/post_bulk_creator.rb b/backend/app/services/post_bulk_creator.rb index e525c57..38ec06e 100644 --- a/backend/app/services/post_bulk_creator.rb +++ b/backend/app/services/post_bulk_creator.rb @@ -66,7 +66,7 @@ class PostBulkCreator PostCreatePreflight.new( attributes: attributes, thumbnail: thumbnail_for(index, attributes), - host: @host).run + host: @host).run(locale) if preflight[:existing_post_id].present? return { status: 'skipped', diff --git a/backend/app/services/post_create_plan.rb b/backend/app/services/post_create_plan.rb index e1279a1..58fbaf2 100644 --- a/backend/app/services/post_create_plan.rb +++ b/backend/app/services/post_create_plan.rb @@ -12,8 +12,8 @@ class PostCreatePlan direct_tag_specs, tag_sections = parse_direct_tag_specs(locale) default_tag_specs = build_default_tag_specs(locale, direct_tag_specs) snapshot_tag_specs = merge_tag_specs(direct_tag_specs + default_tag_specs) - preload_existing_tags_by_name!(snapshot_tag_specs.map { _1[:name] }) - validate_new_tag_specs!(snapshot_tag_specs) + preload_existing_tags_by_name!(locale, snapshot_tag_specs.map { _1[:name] }) + validate_new_tag_specs!(locale, snapshot_tag_specs) post_tag_specs = expand_parent_tag_specs(locale, snapshot_tag_specs) video_ms = normalise_video_ms(snapshot_tag_specs) validate_video_sections!(video_ms, tag_sections) @@ -49,7 +49,9 @@ class PostCreatePlan tag_names.each do |raw_name| tag_name, category, sections = parse_raw_tag_name(locale, raw_name) existing_tag = existing_tags_by_name(locale)[tag_name] - raise Tag::DeprecatedTagNormalisationError, [existing_tag.name] if existing_tag&.deprecated? + if existing_tag&.deprecated? + raise Tag::DeprecatedTagNormalisationError, [existing_tag.name(locale.language_code)] + end direct_tag_specs << { name: tag_name, @@ -106,17 +108,18 @@ class PostCreatePlan default_tag_specs end - def validate_new_tag_specs! specs + def validate_new_tag_specs! locale, specs Array(specs).each do |spec| - next if existing_tags_by_name.key?(spec[:name]) + next if existing_tags_by_name(locale).key?(spec[:name]) - validate_new_tag_spec!(spec) + validate_new_tag_spec!(locale, spec) end end - def validate_new_tag_spec! spec - tag_name = TagName.new(name: spec[:name]) - tag = Tag.new(category: spec[:category], tag_name:) + def validate_new_tag_spec! locale, spec + tag_name = TagName.new(name: spec[:name], language_code: locale.language_code, + script_code: locale.script_code, primary_flg: true) + tag = Tag.new(category: spec[:category]) return if tag_name.valid? && tag.valid? post = Post.new @@ -139,7 +142,7 @@ class PostCreatePlan Tag.expand_parent_tags(existing_snapshot_tags) .reject(&:deprecated?) .map { |tag| - { name: tag.name, + { name: tag.name(locale.language_code), category: tag.category.to_sym } } merge_tag_specs(snapshot_tag_specs + expanded_parent_specs) @@ -161,7 +164,9 @@ class PostCreatePlan def existing_tags_by_name locale @existing_tags_by_name ||= begin names = tag_names.map { canonical_tag_name_without_sections(locale, _1) }.uniq - Tag.joins(:tag_name).where(tag_names: { name: names }).index_by(&:name) + TagName.where(language_code: locale.language_code, primary_flg: true, name: names) + .includes(:tag) + .each_with_object({ }) { |tag_name, tags| tags[tag_name.name] = tag_name.tag } end end @@ -171,9 +176,11 @@ class PostCreatePlan return if missing_names.empty? existing_tags_by_name(locale).merge!( - Tag.joins(:tag_name) - .where(tag_names: { name: missing_names }) - .index_by(&:name)) + TagName.where(language_code: locale.language_code, + primary_flg: true, + name: missing_names) + .includes(:tag) + .each_with_object({ }) { |tag_name, tags| tags[tag_name.name] = tag_name.tag }) end def canonical_tag_name_without_sections locale, raw_name @@ -266,8 +273,8 @@ class PostCreatePlan tag_name = TagName.find_by(language_code: locale.language_code, name:) return name if !(tag_name) || tag_name.primary? - TagName.find_by!(language_code: locale.language_code, - tag_id: tag_name.tag_id, - primary_flg: true).name + TagName.find_by(language_code: locale.language_code, + tag_id: tag_name.tag_id, + primary_flg: true)&.name || name end end diff --git a/backend/app/services/post_create_preflight.rb b/backend/app/services/post_create_preflight.rb index 04d3492..24eb21a 100644 --- a/backend/app/services/post_create_preflight.rb +++ b/backend/app/services/post_create_preflight.rb @@ -15,7 +15,7 @@ class PostCreatePreflight @host = host end - def run + def run locale preview = PostImportPreviewer.new.preview_rows( rows: [preview_row], fetch_metadata: false).first @@ -53,7 +53,7 @@ class PostCreatePreflight original_created_from: preview[:attributes]['original_created_from'], original_created_before: preview[:attributes]['original_created_before'], duration: preview[:attributes]['duration'], - video_ms: preview[:attributes]['video_ms'] }).build! + video_ms: preview[:attributes]['video_ms'] }).build!(locale) { url: plan[:url], diff --git a/backend/app/services/post_creator.rb b/backend/app/services/post_creator.rb index f328068..fe3e6a1 100644 --- a/backend/app/services/post_creator.rb +++ b/backend/app/services/post_creator.rb @@ -24,7 +24,10 @@ class PostCreator snapshot_tags = planned_snapshot_tags(locale) post_tags = planned_post_tags(locale) sections = planned_sections(locale) - TagVersioning.record_tag_snapshots!(snapshot_tags, created_by_user: @actor) + TagVersioning.record_tag_snapshots!( + snapshot_tags, + created_by_user: @actor, + language_code: locale.language_code) post.video_ms = planned_video_ms(locale) post.save! sync_post_tags!(post, post_tags, sections) @@ -70,7 +73,8 @@ class PostCreator tag_sections: materialise_sections( @attributes[:tag_sections] || { }, snapshot_tags, - post_tags), + post_tags, + locale), normalised_parent_post_ids: @attributes[:normalised_parent_post_ids] || [], video_ms: @attributes[:video_ms] } else @@ -81,15 +85,16 @@ class PostCreator def build_materialised_plan locale plan = PostCreatePlan.new(attributes: @attributes).build!(locale) - snapshot_tags = materialise_tags(plan[:snapshot_tag_specs] || []) - post_tags = materialise_tags(plan[:post_tag_specs] || []) + snapshot_tags = materialise_tags(locale, plan[:snapshot_tag_specs] || []) + post_tags = materialise_tags(locale, plan[:post_tag_specs] || []) { snapshot_tags: snapshot_tags, post_tags: post_tags, tag_sections: materialise_sections( plan[:tag_sections] || { }, snapshot_tags, - post_tags), + post_tags, + locale), normalised_parent_post_ids: plan[:normalised_parent_post_ids] || [], video_ms: plan[:video_ms] } end @@ -106,10 +111,10 @@ class PostCreator end.values end - def materialise_sections sections_by_name, snapshot_tags, post_tags - tags_by_name = post_tags.index_by(&:name) + def materialise_sections sections_by_name, snapshot_tags, post_tags, locale = Locale.nipponese + tags_by_name = post_tags.index_by { _1.name(locale.language_code) } snapshot_tags.each do |tag| - tags_by_name[tag.name] ||= tag + tags_by_name[tag.name(locale.language_code)] ||= tag end sections_by_name.each_with_object({ }) do |(tag_name, ranges), sections| diff --git a/backend/app/services/post_import_previewer.rb b/backend/app/services/post_import_previewer.rb index 0a812f5..6ce25e2 100644 --- a/backend/app/services/post_import_previewer.rb +++ b/backend/app/services/post_import_previewer.rb @@ -16,7 +16,7 @@ class PostImportPreviewer THUMBNAIL_FETCH_WARNING = 'サムネールを取得できませんでした.'.freeze METADATA_FETCH_WARNING = '自動取得に失敗しました.'.freeze - def preview_rows rows:, fetch_metadata: true, metadata_cache: { } + def preview_rows locale, rows:, fetch_metadata: true, metadata_cache: { } prepared_rows = rows.map { prepare_row(_1) } url_counts = prepared_rows.filter_map { _1[:normal_url] }.tally existing_posts = @@ -36,7 +36,7 @@ class PostImportPreviewer existing_posts, url_counts) prepared_rows.map { |row| - preview_row(row, + preview_row(locale, row, fetch_metadata:, metadata_cache:, existing_posts:, @@ -59,7 +59,7 @@ class PostImportPreviewer source.merge(url_text: url, normal_url:, url_error: validate_url_safety(normal_url)) end - def preview_row row, + def preview_row locale, row, fetch_metadata:, metadata_cache:, existing_posts:, @@ -124,7 +124,8 @@ class PostImportPreviewer attributes['url'] = url validate_basic_data(attributes, validation_errors) - validate_preview_tags(merged_tags(tag_sources, provenance['tags']), + validate_preview_tags(locale, + merged_tags(tag_sources, provenance['tags']), validation_errors, known_tags) validate_parents(attributes['parent_post_ids'], validation_errors, existing_parent_ids) @@ -362,11 +363,9 @@ class PostImportPreviewer }.compact.uniq return { } if names.empty? - Tag.joins(:tag_name) - .where(tag_names: { name: names }) - .includes(:tag_name) - .to_a - .index_by(&:name) + TagName.where(language_code: 'ja', primary_flg: true, name: names) + .includes(:tag) + .each_with_object({ }) { |tag_name, tags| tags[tag_name.name] = tag_name.tag } end def preload_parent_ids prepared_rows @@ -437,19 +436,21 @@ class PostImportPreviewer sources['automatic'].to_s end - def preview_tag_names raw + def preview_tag_names locale, raw names = raw.to_s.split return [] if names.empty? if names.any? { _1.downcase.start_with?('nico:') } return [] end - names.map { |name| TagName.canonicalise(name.sub(/\[.*\]\z/, '')).first } + names.map { |name| + TagName.canonicalise(locale, name.sub(/\[.*\]\z/, '')).first + } rescue Tag::SectionLiteralParseError [] end - def validate_preview_tags raw, errors, known_tags + def validate_preview_tags locale, raw, errors, known_tags names = raw.to_s.split return if names.empty? if names.any? { _1.downcase.start_with?('nico:') } @@ -457,7 +458,9 @@ class PostImportPreviewer return end - parsed = names.map { |name| TagName.canonicalise(name.sub(/\[.*\]\z/, '')).first } + parsed = names.map { |name| + TagName.canonicalise(locale, name.sub(/\[.*\]\z/, '')).first + } existing = parsed.filter_map { known_tags[_1] } deprecated = existing.select(&:deprecated?).map(&:name) errors[:tags] = ["廃止済みタグがあります: #{ deprecated.join(' ') }"] if deprecated.present? diff --git a/backend/app/services/post_metadata_fetcher.rb b/backend/app/services/post_metadata_fetcher.rb index a8dcb6d..c5e2eaf 100644 --- a/backend/app/services/post_metadata_fetcher.rb +++ b/backend/app/services/post_metadata_fetcher.rb @@ -47,9 +47,9 @@ class PostMetadataFetcher existing_tags = Tag - .joins(:tag_name) - .where(tag_names: { name: names }) - .index_by(&:name) + .joins(:tag_names) + .where(tag_names: { language_code: 'ja', primary_flg: true, name: names }) + .index_by { _1.name('ja') } names.map { |name| tag = existing_tags[name] diff --git a/backend/app/services/tag_version_recorder.rb b/backend/app/services/tag_version_recorder.rb index a786058..c7c8bd4 100644 --- a/backend/app/services/tag_version_recorder.rb +++ b/backend/app/services/tag_version_recorder.rb @@ -1,10 +1,11 @@ class TagVersionRecorder < VersionRecorder - def self.record! tag:, event_type:, created_by_user: - new(tag:, event_type:, created_by_user:).record! + def self.record! tag:, event_type:, created_by_user:, language_code: 'ja' + new(tag:, event_type:, created_by_user:, language_code:).record! end - def initialize tag:, event_type:, created_by_user: + def initialize tag:, event_type:, created_by_user:, language_code: super(record: tag, event_type:, created_by_user:) + @language_code = language_code end private @@ -14,10 +15,10 @@ class TagVersionRecorder < VersionRecorder def record_key = :tag def snapshot_attributes - { name: @record.name, + { name: @record.name(@language_code), category: @record.category, deprecated_at: @record.deprecated_at, - aliases: @record.snapshot_aliases.join(' '), + aliases: @record.snapshot_aliases(@language_code).join(' '), parent_tag_ids: @record.snapshot_parent_tag_ids.join(' ') } end end diff --git a/backend/app/services/tag_versioning.rb b/backend/app/services/tag_versioning.rb index d874a3e..4990801 100644 --- a/backend/app/services/tag_versioning.rb +++ b/backend/app/services/tag_versioning.rb @@ -1,22 +1,22 @@ class TagVersioning - def self.record! tag, event_type:, created_by_user: - TagVersionRecorder.record!(tag:, event_type:, created_by_user:) + def self.record! tag, event_type:, created_by_user:, language_code: 'ja' + TagVersionRecorder.record!(tag:, event_type:, created_by_user:, language_code:) end - def self.ensure_snapshot! tag, created_by_user: + def self.ensure_snapshot! tag, created_by_user:, language_code: 'ja' return if tag.tag_versions.exists? - TagVersionRecorder.record!(tag:, event_type: :create, created_by_user:) + TagVersionRecorder.record!(tag:, event_type: :create, created_by_user:, language_code:) end - def self.record_tag_snapshot! tag, created_by_user: + def self.record_tag_snapshot! tag, created_by_user:, language_code: 'ja' event_type = tag.tag_versions.exists? ? :update : :create - record!(tag, event_type:, created_by_user:) + record!(tag, event_type:, created_by_user:, language_code:) end - def self.record_tag_snapshots! tags, created_by_user: + def self.record_tag_snapshots! tags, created_by_user:, language_code: 'ja' tags.each do |tag| - record_tag_snapshot!(tag, created_by_user:) + record_tag_snapshot!(tag, created_by_user:, language_code:) end end end diff --git a/backend/app/services/theatre_post_selector.rb b/backend/app/services/theatre_post_selector.rb index 124c913..8d5ab32 100644 --- a/backend/app/services/theatre_post_selector.rb +++ b/backend/app/services/theatre_post_selector.rb @@ -41,7 +41,7 @@ class TheatrePostSelector def weighted_candidates @weighted_candidates ||= begin penalties = tag_penalties - posts = eligible_posts.includes(tags: :tag_name).to_a + posts = eligible_posts.includes(tags: :tag_names).to_a posts.map do |post| post_tags = post.tags.to_a @@ -82,7 +82,7 @@ class TheatrePostSelector def tag_penalty_json return [] if tag_penalties.empty? - tags = Tag.where(id: tag_penalties.keys).includes(:tag_name).index_by(&:id) + tags = Tag.where(id: tag_penalties.keys).includes(:tag_names).index_by(&:id) tag_penalties .map { |tag_id, penalty| @@ -113,7 +113,7 @@ class TheatrePostSelector def light_tag_json tag { id: tag.id, - name: tag.name, + name: tag.name('ja'), category: tag.category } end end