#55 いったん中断;外部タグ分離優先
このコミットが含まれているのは:
@@ -92,4 +92,6 @@ class ApplicationController < ActionController::API
|
|||||||
|
|
||||||
value
|
value
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def resolve_locale! = Locale.find_by(code: params[:locale]) || Locale.nipponese
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -72,6 +72,7 @@ class MaterialsController < ApplicationController
|
|||||||
return head :unauthorized unless current_user
|
return head :unauthorized unless current_user
|
||||||
return head :forbidden unless current_user.gte_member?
|
return head :forbidden unless current_user.gte_member?
|
||||||
|
|
||||||
|
locale = resolve_locale!
|
||||||
tag_name_raw = params[:tag].to_s.strip
|
tag_name_raw = params[:tag].to_s.strip
|
||||||
file = params[:file]
|
file = params[:file]
|
||||||
file_sha256 = MaterialFileSha256.from_upload(file)
|
file_sha256 = MaterialFileSha256.from_upload(file)
|
||||||
@@ -89,7 +90,7 @@ class MaterialsController < ApplicationController
|
|||||||
|
|
||||||
begin
|
begin
|
||||||
Material.transaction do
|
Material.transaction do
|
||||||
tag = resolve_material_tag!(tag_name_raw)
|
tag = resolve_material_tag!(locale, tag_name_raw)
|
||||||
material = Material.new(tag:, url:,
|
material = Material.new(tag:, url:,
|
||||||
created_by_user: current_user,
|
created_by_user: current_user,
|
||||||
updated_by_user: current_user)
|
updated_by_user: current_user)
|
||||||
@@ -237,9 +238,7 @@ class MaterialsController < ApplicationController
|
|||||||
end
|
end
|
||||||
|
|
||||||
def resolve_material_tag! locale, tag_name_raw
|
def resolve_material_tag! locale, tag_name_raw
|
||||||
tag_name = TagName.find_or_create_by!(language_code: locale.language_code,
|
Tag.find_or_create_by_tag_name!(locale, tag_name_raw, category: :material)
|
||||||
name: tag_name_raw)
|
|
||||||
tag_name.tag || Tag.create!(tag_name:, category: :material)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def material_index_needs_tag_name? filters
|
def material_index_needs_tag_name? filters
|
||||||
|
|||||||
@@ -70,6 +70,8 @@ class NicoTagsController < ApplicationController
|
|||||||
return head :unauthorized unless current_user
|
return head :unauthorized unless current_user
|
||||||
return head :forbidden unless current_user.gte_member?
|
return head :forbidden unless current_user.gte_member?
|
||||||
|
|
||||||
|
locale = resolve_locale!
|
||||||
|
|
||||||
id = params[:id].to_i
|
id = params[:id].to_i
|
||||||
|
|
||||||
tag = Tag.find(id)
|
tag = Tag.find(id)
|
||||||
@@ -79,8 +81,9 @@ class NicoTagsController < ApplicationController
|
|||||||
linked_tags = nil
|
linked_tags = nil
|
||||||
|
|
||||||
ApplicationRecord.transaction do
|
ApplicationRecord.transaction do
|
||||||
linked_tags = Tag.normalise_tags!(linked_tag_names, with_tagme: false,
|
linked_tags = Tag.normalise_tags!(locale, linked_tag_names,
|
||||||
with_no_deerjikist: false)
|
with_tagme: false,
|
||||||
|
with_no_deerjikist: false)
|
||||||
if linked_tags.any? { |t| t.nico? }
|
if linked_tags.any? { |t| t.nico? }
|
||||||
raise Tag::NicoTagNormalisationError
|
raise Tag::NicoTagNormalisationError
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -690,9 +690,10 @@ class PostsController < ApplicationController
|
|||||||
def post_incoming_snapshot locale:, title:, original_created_from:, original_created_before:,
|
def post_incoming_snapshot locale:, title:, original_created_from:, original_created_before:,
|
||||||
tag_names:, video_ms_param:, duration_param:, parent_post_ids:
|
tag_names:, video_ms_param:, duration_param:, parent_post_ids:
|
||||||
validate_original_created_values!(original_created_from, original_created_before)
|
validate_original_created_values!(original_created_from, original_created_before)
|
||||||
Tag.normalise_tags!(locale, tag_names, with_tagme: false, deny_deprecated: true,
|
Tag.normalise_tags!(locale, tag_names,
|
||||||
with_sections: true) =>
|
with_tagme: false,
|
||||||
{ tags:, sections: }
|
deny_deprecated: true,
|
||||||
|
with_sections: true) => { tags:, sections: }
|
||||||
|
|
||||||
tags = Tag.expand_parent_tags(tags).reject(&:deprecated?)
|
tags = Tag.expand_parent_tags(tags).reject(&:deprecated?)
|
||||||
video_ms = normalise_video_ms(tags, video_ms_param:, duration_param:)
|
video_ms = normalise_video_ms(tags, video_ms_param:, duration_param:)
|
||||||
|
|||||||
@@ -278,6 +278,8 @@ class TagsController < ApplicationController
|
|||||||
|
|
||||||
return unless validate_tag_rename(tag, name)
|
return unless validate_tag_rename(tag, name)
|
||||||
|
|
||||||
|
locale = resolve_locale!
|
||||||
|
|
||||||
alias_names = params[:aliases].to_s.split.uniq
|
alias_names = params[:aliases].to_s.split.uniq
|
||||||
parent_names = params[:parent_tags].to_s.split.uniq
|
parent_names = params[:parent_tags].to_s.split.uniq
|
||||||
deprecated = bool?(:deprecated)
|
deprecated = bool?(:deprecated)
|
||||||
@@ -308,7 +310,7 @@ class TagsController < ApplicationController
|
|||||||
alias_names.delete(name)
|
alias_names.delete(name)
|
||||||
|
|
||||||
update_aliases!(tag, alias_names)
|
update_aliases!(tag, alias_names)
|
||||||
update_parent_tags!(tag, parent_names)
|
update_parent_tags!(locale, tag, parent_names)
|
||||||
|
|
||||||
tag.reload
|
tag.reload
|
||||||
|
|
||||||
@@ -659,10 +661,11 @@ class TagsController < ApplicationController
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def update_parent_tags! tag, parent_names
|
def update_parent_tags! locale, tag, parent_names
|
||||||
parent_tags = Tag.normalise_tags!(parent_names, with_tagme: false,
|
parent_tags = Tag.normalise_tags!(locale, parent_names,
|
||||||
with_no_deerjikist: false,
|
with_tagme: false,
|
||||||
deny_nico: true)
|
with_no_deerjikist: false,
|
||||||
|
deny_nico: true)
|
||||||
|
|
||||||
old_parent_tags = tag.parents.to_a
|
old_parent_tags = tag.parents.to_a
|
||||||
|
|
||||||
|
|||||||
@@ -242,12 +242,14 @@ class Tag < ApplicationRecord
|
|||||||
end
|
end
|
||||||
|
|
||||||
tag = tn.tag
|
tag = tn.tag
|
||||||
unless tag
|
if tag
|
||||||
tag = Tag.find_undiscard_or_create_by!(tag_name_id: tn.id) do
|
tag.update!(tag_name_id: tn.id) if tag.tag_name_id != tn.id
|
||||||
_1.category = category
|
return tag
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
tag = Tag.create!(tag_name: tn, category:)
|
||||||
|
tn.update!(tag:)
|
||||||
|
|
||||||
tag
|
tag
|
||||||
rescue ActiveRecord::RecordNotUnique
|
rescue ActiveRecord::RecordNotUnique
|
||||||
retry
|
retry
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
class TagName < ApplicationRecord
|
class TagName < ApplicationRecord
|
||||||
belongs_to :tag
|
belongs_to :tag, optional: true
|
||||||
has_one :wiki_page
|
has_one :wiki_page
|
||||||
|
|
||||||
belongs_to :canonical, class_name: 'TagName', optional: true
|
belongs_to :canonical, class_name: 'TagName', optional: true
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ class PostCreator
|
|||||||
@field_warnings = { }
|
@field_warnings = { }
|
||||||
end
|
end
|
||||||
|
|
||||||
def create!
|
def create!(locale)
|
||||||
thumbnail_attachment = prepare_thumbnail_attachment
|
thumbnail_attachment = prepare_thumbnail_attachment
|
||||||
post = Post.new(title: @attributes[:title].presence,
|
post = Post.new(title: @attributes[:title].presence,
|
||||||
url: @attributes[:url],
|
url: @attributes[:url],
|
||||||
@@ -25,7 +25,7 @@ class PostCreator
|
|||||||
post_tags = planned_post_tags
|
post_tags = planned_post_tags
|
||||||
sections = planned_sections
|
sections = planned_sections
|
||||||
TagVersioning.record_tag_snapshots!(snapshot_tags, created_by_user: @actor)
|
TagVersioning.record_tag_snapshots!(snapshot_tags, created_by_user: @actor)
|
||||||
post.video_ms = planned_video_ms
|
post.video_ms = planned_video_ms(locale)
|
||||||
post.save!
|
post.save!
|
||||||
sync_post_tags!(post, post_tags, sections)
|
sync_post_tags!(post, post_tags, sections)
|
||||||
sync_parent_posts!(post, planned_parent_post_ids)
|
sync_parent_posts!(post, planned_parent_post_ids)
|
||||||
@@ -53,15 +53,15 @@ class PostCreator
|
|||||||
|
|
||||||
def planned_parent_post_ids = planned_create_attributes[:normalised_parent_post_ids]
|
def planned_parent_post_ids = planned_create_attributes[:normalised_parent_post_ids]
|
||||||
|
|
||||||
def planned_video_ms
|
def planned_video_ms locale
|
||||||
planned_create_attributes[:video_ms]
|
planned_create_attributes(locale)[:video_ms]
|
||||||
end
|
end
|
||||||
|
|
||||||
def planned_create_attributes
|
def planned_create_attributes locale
|
||||||
@planned_create_attributes ||= begin
|
@planned_create_attributes ||= begin
|
||||||
if @attributes.key?(:snapshot_tag_specs)
|
if @attributes.key?(:snapshot_tag_specs)
|
||||||
snapshot_tags = materialise_tags(@attributes[:snapshot_tag_specs] || [])
|
snapshot_tags = materialise_tags(locale, @attributes[:snapshot_tag_specs] || [])
|
||||||
post_tags = materialise_tags(@attributes[:post_tag_specs] || [])
|
post_tags = materialise_tags(locale, @attributes[:post_tag_specs] || [])
|
||||||
{
|
{
|
||||||
snapshot_tags: snapshot_tags,
|
snapshot_tags: snapshot_tags,
|
||||||
post_tags: post_tags,
|
post_tags: post_tags,
|
||||||
@@ -92,13 +92,13 @@ class PostCreator
|
|||||||
video_ms: plan[:video_ms] }
|
video_ms: plan[:video_ms] }
|
||||||
end
|
end
|
||||||
|
|
||||||
def materialise_tags specs
|
def materialise_tags locale, specs
|
||||||
Array(specs).each_with_object({ }) do |spec, tags|
|
Array(specs).each_with_object({ }) do |spec, tags|
|
||||||
name = spec[:name] || spec['name']
|
name = spec[:name] || spec['name']
|
||||||
category = spec[:category] || spec['category']
|
category = spec[:category] || spec['category']
|
||||||
next if name.blank? || category.blank?
|
next if name.blank? || category.blank?
|
||||||
|
|
||||||
tag = Tag.find_or_create_by_tag_name!(name, category:)
|
tag = Tag.find_or_create_by_tag_name!(locale, name, category:)
|
||||||
tag.update!(category:) if tag.category.to_sym != category.to_sym
|
tag.update!(category:) if tag.category.to_sym != category.to_sym
|
||||||
tags[name] ||= tag
|
tags[name] ||= tag
|
||||||
end.values
|
end.values
|
||||||
|
|||||||
生成ファイル
+59
-13
@@ -72,6 +72,7 @@ ActiveRecord::Schema[8.0].define(version: 2026_09_21_030000) do
|
|||||||
t.index ["correct_post_id"], name: "index_gekanator_games_on_correct_post_id"
|
t.index ["correct_post_id"], name: "index_gekanator_games_on_correct_post_id"
|
||||||
t.index ["guessed_post_id"], name: "index_gekanator_games_on_guessed_post_id"
|
t.index ["guessed_post_id"], name: "index_gekanator_games_on_guessed_post_id"
|
||||||
t.index ["user_id"], name: "index_gekanator_games_on_user_id"
|
t.index ["user_id"], name: "index_gekanator_games_on_user_id"
|
||||||
|
t.check_constraint "`question_count` >= 0", name: "chk_gekanator_games_question_count_nonnegative"
|
||||||
end
|
end
|
||||||
|
|
||||||
create_table "gekanator_question_examples", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
|
create_table "gekanator_question_examples", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
|
||||||
@@ -129,6 +130,24 @@ ActiveRecord::Schema[8.0].define(version: 2026_09_21_030000) do
|
|||||||
t.index ["ip_address"], name: "index_ip_addresses_on_ip_address", unique: true
|
t.index ["ip_address"], name: "index_ip_addresses_on_ip_address", unique: true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
create_table "languages", primary_key: "code", id: { type: :string, limit: 16 }, charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
|
||||||
|
t.string "name", null: false
|
||||||
|
t.datetime "deprecated_at"
|
||||||
|
t.datetime "created_at", null: false
|
||||||
|
t.index ["deprecated_at"], name: "index_languages_on_deprecated_at"
|
||||||
|
end
|
||||||
|
|
||||||
|
create_table "locales", primary_key: "code", id: { type: :string, limit: 32 }, charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
|
||||||
|
t.string "language_code", limit: 16, null: false
|
||||||
|
t.string "script_code", limit: 4, null: false
|
||||||
|
t.string "name", null: false
|
||||||
|
t.datetime "deprecated_at"
|
||||||
|
t.datetime "created_at", null: false
|
||||||
|
t.index ["deprecated_at"], name: "index_locales_on_deprecated_at"
|
||||||
|
t.index ["language_code"], name: "index_locales_on_language_code"
|
||||||
|
t.index ["script_code"], name: "fk_rails_0b74ce96a8"
|
||||||
|
end
|
||||||
|
|
||||||
create_table "material_export_items", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
|
create_table "material_export_items", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
|
||||||
t.bigint "material_id", null: false
|
t.bigint "material_id", null: false
|
||||||
t.string "profile", default: "legacy_drive", null: false
|
t.string "profile", default: "legacy_drive", null: false
|
||||||
@@ -274,9 +293,10 @@ ActiveRecord::Schema[8.0].define(version: 2026_09_21_030000) do
|
|||||||
t.datetime "created_at", null: false
|
t.datetime "created_at", null: false
|
||||||
t.bigint "created_by_user_id"
|
t.bigint "created_by_user_id"
|
||||||
t.index ["created_at"], name: "index_nico_tag_versions_on_created_at"
|
t.index ["created_at"], name: "index_nico_tag_versions_on_created_at"
|
||||||
t.index ["created_by_user_id", "created_at"], name: "index_nico_tag_versions_on_created_by_user_id_and_created_at"
|
t.index ["created_by_user_id", "created_at"], name: "index_nico_tag_versions_on_created_by_user_id_and_created_at", order: { created_at: :desc }
|
||||||
t.index ["tag_id", "created_at"], name: "index_nico_tag_versions_on_tag_id_and_created_at"
|
t.index ["tag_id", "created_at"], name: "index_nico_tag_versions_on_tag_id_and_created_at", order: { created_at: :desc }
|
||||||
t.index ["tag_id", "version_no"], name: "index_nico_tag_versions_on_tag_id_and_version_no", unique: true
|
t.index ["tag_id", "version_no"], name: "index_nico_tag_versions_on_tag_id_and_version_no", unique: true
|
||||||
|
t.check_constraint "`version_no` > 0", name: "nico_tag_versions_version_no_positive"
|
||||||
end
|
end
|
||||||
|
|
||||||
create_table "post_implications", primary_key: ["post_id", "parent_post_id"], charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
|
create_table "post_implications", primary_key: ["post_id", "parent_post_id"], charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
|
||||||
@@ -285,13 +305,14 @@ ActiveRecord::Schema[8.0].define(version: 2026_09_21_030000) do
|
|||||||
t.datetime "created_at", null: false
|
t.datetime "created_at", null: false
|
||||||
t.datetime "updated_at", null: false
|
t.datetime "updated_at", null: false
|
||||||
t.index ["parent_post_id"], name: "index_post_implications_on_parent_post_id"
|
t.index ["parent_post_id"], name: "index_post_implications_on_parent_post_id"
|
||||||
|
t.check_constraint "`post_id` <> `parent_post_id`", name: "chk_post_implications_no_self"
|
||||||
end
|
end
|
||||||
|
|
||||||
create_table "post_similarities", primary_key: ["post_id", "target_post_id"], charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
|
create_table "post_similarities", primary_key: ["post_id", "target_post_id"], charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
|
||||||
t.bigint "post_id", null: false
|
t.bigint "post_id", null: false
|
||||||
t.bigint "target_post_id", null: false
|
t.bigint "target_post_id", null: false
|
||||||
t.float "cos", null: false
|
t.float "cos", null: false
|
||||||
t.index ["post_id", "cos"], name: "index_post_similarities_on_post_id_and_cos"
|
t.index ["post_id", "cos"], name: "index_post_similarities_on_post_id_and_cos", order: { cos: :desc }
|
||||||
t.index ["target_post_id"], name: "index_post_similarities_on_target_post_id"
|
t.index ["target_post_id"], name: "index_post_similarities_on_target_post_id"
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -347,6 +368,8 @@ ActiveRecord::Schema[8.0].define(version: 2026_09_21_030000) do
|
|||||||
t.index ["post_id"], name: "index_post_versions_on_post_id"
|
t.index ["post_id"], name: "index_post_versions_on_post_id"
|
||||||
t.index ["video_ms", "post_id"], name: "idx_post_versions_video_ms_post_id"
|
t.index ["video_ms", "post_id"], name: "idx_post_versions_video_ms_post_id"
|
||||||
t.check_constraint "(`video_ms` is null) or (`video_ms` > 0)", name: "chk_post_versions_video_ms_positive"
|
t.check_constraint "(`video_ms` is null) or (`video_ms` > 0)", name: "chk_post_versions_video_ms_positive"
|
||||||
|
t.check_constraint "`event_type` in (_utf8mb4'create',_utf8mb4'update',_utf8mb4'discard',_utf8mb4'restore')", name: "post_versions_event_type_valid"
|
||||||
|
t.check_constraint "`version_no` > 0", name: "post_versions_version_no_positive"
|
||||||
t.check_constraint "json_schema_valid(_utf8mb4'{\"type\":\"array\",\"items\":{\"type\":\"object\",\"properties\":{\"id\":{\"type\":\"integer\",\"minimum\":1},\"version_no\":{\"type\":\"integer\",\"minimum\":1},\"name\":{\"type\":\"string\",\"minLength\":1},\"category\":{\"type\":\"string\",\"enum\":[\"deerjikist\",\"meme\",\"character\",\"general\",\"material\",\"meta\",\"nico\"]},\"sections\":{\"type\":\"array\",\"items\":{\"type\":\"object\",\"properties\":{\"begin_ms\":{\"type\":\"integer\",\"minimum\":0},\"end_ms\":{\"type\":[\"integer\",\"null\"],\"minimum\":0}},\"required\":[\"begin_ms\",\"end_ms\"],\"additionalProperties\":false}}},\"required\":[\"id\",\"version_no\",\"name\",\"category\",\"sections\"],\"additionalProperties\":false}}',`tags_json`)", name: "chk_post_versions_tags_json_schema"
|
t.check_constraint "json_schema_valid(_utf8mb4'{\"type\":\"array\",\"items\":{\"type\":\"object\",\"properties\":{\"id\":{\"type\":\"integer\",\"minimum\":1},\"version_no\":{\"type\":\"integer\",\"minimum\":1},\"name\":{\"type\":\"string\",\"minLength\":1},\"category\":{\"type\":\"string\",\"enum\":[\"deerjikist\",\"meme\",\"character\",\"general\",\"material\",\"meta\",\"nico\"]},\"sections\":{\"type\":\"array\",\"items\":{\"type\":\"object\",\"properties\":{\"begin_ms\":{\"type\":\"integer\",\"minimum\":0},\"end_ms\":{\"type\":[\"integer\",\"null\"],\"minimum\":0}},\"required\":[\"begin_ms\",\"end_ms\"],\"additionalProperties\":false}}},\"required\":[\"id\",\"version_no\",\"name\",\"category\",\"sections\"],\"additionalProperties\":false}}',`tags_json`)", name: "chk_post_versions_tags_json_schema"
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -365,6 +388,14 @@ ActiveRecord::Schema[8.0].define(version: 2026_09_21_030000) do
|
|||||||
t.index ["url"], name: "index_posts_on_url", unique: true
|
t.index ["url"], name: "index_posts_on_url", unique: true
|
||||||
t.index ["video_ms", "id"], name: "idx_posts_video_ms_id"
|
t.index ["video_ms", "id"], name: "idx_posts_video_ms_id"
|
||||||
t.check_constraint "(`video_ms` is null) or (`video_ms` > 0)", name: "chk_posts_video_ms_positive"
|
t.check_constraint "(`video_ms` is null) or (`video_ms` > 0)", name: "chk_posts_video_ms_positive"
|
||||||
|
t.check_constraint "`version_no` > 0", name: "chk_posts_version_no_positive"
|
||||||
|
end
|
||||||
|
|
||||||
|
create_table "scripts", primary_key: "code", id: { type: :string, limit: 4 }, charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
|
||||||
|
t.string "name", null: false
|
||||||
|
t.datetime "deprecated_at"
|
||||||
|
t.datetime "created_at", null: false
|
||||||
|
t.index ["deprecated_at"], name: "index_scripts_on_deprecated_at"
|
||||||
end
|
end
|
||||||
|
|
||||||
create_table "settings", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
|
create_table "settings", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
|
||||||
@@ -372,12 +403,6 @@ ActiveRecord::Schema[8.0].define(version: 2026_09_21_030000) do
|
|||||||
t.datetime "created_at", null: false
|
t.datetime "created_at", null: false
|
||||||
t.datetime "updated_at", null: false
|
t.datetime "updated_at", null: false
|
||||||
t.string "theme", default: "system", null: false
|
t.string "theme", default: "system", null: false
|
||||||
t.string "display_density", default: "comfortable", null: false
|
|
||||||
t.string "font_size", default: "normal", null: false
|
|
||||||
t.integer "post_list_limit", default: 50, null: false
|
|
||||||
t.string "post_list_order", default: "created_at_desc", null: false
|
|
||||||
t.string "viewed_post_display", default: "show", null: false
|
|
||||||
t.boolean "tag_autocomplete_nico", default: true, null: false
|
|
||||||
t.string "auto_fetch_title", default: "manual", null: false
|
t.string "auto_fetch_title", default: "manual", null: false
|
||||||
t.string "auto_fetch_thumbnail", default: "manual", null: false
|
t.string "auto_fetch_thumbnail", default: "manual", null: false
|
||||||
t.string "wiki_editor_mode", default: "split", null: false
|
t.string "wiki_editor_mode", default: "split", null: false
|
||||||
@@ -405,19 +430,27 @@ ActiveRecord::Schema[8.0].define(version: 2026_09_21_030000) do
|
|||||||
end
|
end
|
||||||
|
|
||||||
create_table "tag_names", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
|
create_table "tag_names", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
|
||||||
|
t.bigint "tag_id"
|
||||||
|
t.string "language_code", limit: 16, null: false
|
||||||
t.string "name", null: false
|
t.string "name", null: false
|
||||||
|
t.string "script_code", limit: 4, null: false
|
||||||
|
t.boolean "primary_flg", null: false
|
||||||
t.bigint "canonical_id"
|
t.bigint "canonical_id"
|
||||||
t.datetime "created_at", null: false
|
t.datetime "created_at", null: false
|
||||||
t.datetime "updated_at", null: false
|
t.datetime "updated_at", null: false
|
||||||
|
t.virtual "primary_tag_id", type: :bigint, as: "(case when `primary_flg` then `tag_id` else NULL end)"
|
||||||
t.index ["canonical_id"], name: "index_tag_names_on_canonical_id"
|
t.index ["canonical_id"], name: "index_tag_names_on_canonical_id"
|
||||||
t.index ["name"], name: "index_tag_names_on_name", unique: true
|
t.index ["language_code", "name"], name: "index_tag_names_on_language_code_and_name", unique: true
|
||||||
|
t.index ["primary_tag_id", "language_code"], name: "index_tag_names_on_primary_tag_id_and_language_code", unique: true
|
||||||
|
t.index ["script_code"], name: "fk_rails_dd783b3d1c"
|
||||||
|
t.index ["tag_id"], name: "index_tag_names_on_tag_id"
|
||||||
end
|
end
|
||||||
|
|
||||||
create_table "tag_similarities", primary_key: ["tag_id", "target_tag_id"], charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
|
create_table "tag_similarities", primary_key: ["tag_id", "target_tag_id"], 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 "target_tag_id", null: false
|
t.bigint "target_tag_id", null: false
|
||||||
t.float "cos", null: false
|
t.float "cos", null: false
|
||||||
t.index ["tag_id", "cos"], name: "index_tag_similarities_on_tag_id_and_cos"
|
t.index ["tag_id", "cos"], name: "index_tag_similarities_on_tag_id_and_cos", order: { cos: :desc }
|
||||||
t.index ["target_tag_id"], name: "index_tag_similarities_on_target_tag_id"
|
t.index ["target_tag_id"], name: "index_tag_similarities_on_target_tag_id"
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -433,9 +466,10 @@ ActiveRecord::Schema[8.0].define(version: 2026_09_21_030000) do
|
|||||||
t.datetime "created_at", null: false
|
t.datetime "created_at", null: false
|
||||||
t.bigint "created_by_user_id"
|
t.bigint "created_by_user_id"
|
||||||
t.index ["created_at"], name: "index_tag_versions_on_created_at"
|
t.index ["created_at"], name: "index_tag_versions_on_created_at"
|
||||||
t.index ["created_by_user_id", "created_at"], name: "index_tag_versions_on_created_by_user_id_and_created_at"
|
t.index ["created_by_user_id", "created_at"], name: "index_tag_versions_on_created_by_user_id_and_created_at", order: { created_at: :desc }
|
||||||
t.index ["tag_id", "created_at"], name: "index_tag_versions_on_tag_id_and_created_at"
|
t.index ["tag_id", "created_at"], name: "index_tag_versions_on_tag_id_and_created_at", order: { created_at: :desc }
|
||||||
t.index ["tag_id", "version_no"], name: "index_tag_versions_on_tag_id_and_version_no", unique: true
|
t.index ["tag_id", "version_no"], name: "index_tag_versions_on_tag_id_and_version_no", unique: true
|
||||||
|
t.check_constraint "`version_no` > 0", name: "tag_versions_version_no_positive"
|
||||||
end
|
end
|
||||||
|
|
||||||
create_table "tags", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
|
create_table "tags", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
|
||||||
@@ -449,6 +483,7 @@ ActiveRecord::Schema[8.0].define(version: 2026_09_21_030000) do
|
|||||||
t.index ["deprecated_at"], name: "index_tags_on_deprecated_at"
|
t.index ["deprecated_at"], name: "index_tags_on_deprecated_at"
|
||||||
t.index ["tag_name_id"], name: "index_tags_on_tag_name_id", unique: true
|
t.index ["tag_name_id"], name: "index_tags_on_tag_name_id", unique: true
|
||||||
t.check_constraint "(`deprecated_at` is null) or (`category` <> _utf8mb4'nico')", name: "chk_tags_deprecated_at_not_nico"
|
t.check_constraint "(`deprecated_at` is null) or (`category` <> _utf8mb4'nico')", name: "chk_tags_deprecated_at_not_nico"
|
||||||
|
t.check_constraint "`version_no` > 0", name: "chk_tags_version_no_positive"
|
||||||
end
|
end
|
||||||
|
|
||||||
create_table "theatre_comments", primary_key: ["theatre_id", "no"], charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
|
create_table "theatre_comments", primary_key: ["theatre_id", "no"], charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
|
||||||
@@ -615,11 +650,13 @@ ActiveRecord::Schema[8.0].define(version: 2026_09_21_030000) do
|
|||||||
t.datetime "created_at", null: false
|
t.datetime "created_at", null: false
|
||||||
t.datetime "updated_at", null: false
|
t.datetime "updated_at", null: false
|
||||||
t.datetime "discarded_at"
|
t.datetime "discarded_at"
|
||||||
|
t.integer "next_asset_no", default: 1, null: false
|
||||||
t.integer "version_no", null: false
|
t.integer "version_no", null: false
|
||||||
t.index ["created_user_id"], name: "index_wiki_pages_on_created_user_id"
|
t.index ["created_user_id"], name: "index_wiki_pages_on_created_user_id"
|
||||||
t.index ["discarded_at"], name: "index_wiki_pages_on_discarded_at"
|
t.index ["discarded_at"], name: "index_wiki_pages_on_discarded_at"
|
||||||
t.index ["tag_name_id"], name: "index_wiki_pages_on_tag_name_id", unique: true
|
t.index ["tag_name_id"], name: "index_wiki_pages_on_tag_name_id", unique: true
|
||||||
t.index ["updated_user_id"], name: "index_wiki_pages_on_updated_user_id"
|
t.index ["updated_user_id"], name: "index_wiki_pages_on_updated_user_id"
|
||||||
|
t.check_constraint "`version_no` > 0", name: "chk_wiki_pages_version_no_positive"
|
||||||
end
|
end
|
||||||
|
|
||||||
create_table "wiki_revision_lines", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
|
create_table "wiki_revision_lines", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
|
||||||
@@ -664,6 +701,8 @@ ActiveRecord::Schema[8.0].define(version: 2026_09_21_030000) do
|
|||||||
t.index ["created_by_user_id"], name: "index_wiki_versions_on_created_by_user_id"
|
t.index ["created_by_user_id"], name: "index_wiki_versions_on_created_by_user_id"
|
||||||
t.index ["wiki_page_id", "version_no"], name: "index_wiki_versions_on_wiki_page_id_and_version_no", unique: true
|
t.index ["wiki_page_id", "version_no"], name: "index_wiki_versions_on_wiki_page_id_and_version_no", unique: true
|
||||||
t.index ["wiki_page_id"], name: "index_wiki_versions_on_wiki_page_id"
|
t.index ["wiki_page_id"], name: "index_wiki_versions_on_wiki_page_id"
|
||||||
|
t.check_constraint "`event_type` in (_utf8mb4'create',_utf8mb4'update',_utf8mb4'discard',_utf8mb4'restore')", name: "wiki_versions_event_type_valid"
|
||||||
|
t.check_constraint "`version_no` > 0", name: "wiki_versions_version_no_positive"
|
||||||
end
|
end
|
||||||
|
|
||||||
add_foreign_key "active_storage_attachments", "active_storage_blobs", column: "blob_id"
|
add_foreign_key "active_storage_attachments", "active_storage_blobs", column: "blob_id"
|
||||||
@@ -680,6 +719,8 @@ ActiveRecord::Schema[8.0].define(version: 2026_09_21_030000) do
|
|||||||
add_foreign_key "gekanator_question_suggestions", "users"
|
add_foreign_key "gekanator_question_suggestions", "users"
|
||||||
add_foreign_key "gekanator_questions", "gekanator_question_suggestions"
|
add_foreign_key "gekanator_questions", "gekanator_question_suggestions"
|
||||||
add_foreign_key "gekanator_questions", "users", column: "created_by_id"
|
add_foreign_key "gekanator_questions", "users", column: "created_by_id"
|
||||||
|
add_foreign_key "locales", "languages", column: "language_code", primary_key: "code"
|
||||||
|
add_foreign_key "locales", "scripts", column: "script_code", primary_key: "code"
|
||||||
add_foreign_key "material_export_items", "materials"
|
add_foreign_key "material_export_items", "materials"
|
||||||
add_foreign_key "material_export_items", "users", column: "created_by_user_id"
|
add_foreign_key "material_export_items", "users", column: "created_by_user_id"
|
||||||
add_foreign_key "material_import_blocks", "users", column: "created_by_user_id"
|
add_foreign_key "material_import_blocks", "users", column: "created_by_user_id"
|
||||||
@@ -711,7 +752,10 @@ ActiveRecord::Schema[8.0].define(version: 2026_09_21_030000) do
|
|||||||
add_foreign_key "settings", "users"
|
add_foreign_key "settings", "users"
|
||||||
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", "languages", column: "language_code", primary_key: "code"
|
||||||
|
add_foreign_key "tag_names", "scripts", column: "script_code", primary_key: "code"
|
||||||
add_foreign_key "tag_names", "tag_names", column: "canonical_id"
|
add_foreign_key "tag_names", "tag_names", column: "canonical_id"
|
||||||
|
add_foreign_key "tag_names", "tags"
|
||||||
add_foreign_key "tag_similarities", "tags"
|
add_foreign_key "tag_similarities", "tags"
|
||||||
add_foreign_key "tag_similarities", "tags", column: "target_tag_id"
|
add_foreign_key "tag_similarities", "tags", column: "target_tag_id"
|
||||||
add_foreign_key "tag_versions", "users", column: "created_by_user_id"
|
add_foreign_key "tag_versions", "users", column: "created_by_user_id"
|
||||||
@@ -740,6 +784,8 @@ ActiveRecord::Schema[8.0].define(version: 2026_09_21_030000) do
|
|||||||
add_foreign_key "user_post_views", "posts"
|
add_foreign_key "user_post_views", "posts"
|
||||||
add_foreign_key "user_post_views", "users"
|
add_foreign_key "user_post_views", "users"
|
||||||
add_foreign_key "user_theme_slots", "users"
|
add_foreign_key "user_theme_slots", "users"
|
||||||
|
add_foreign_key "wiki_assets", "users", column: "created_by_user_id"
|
||||||
|
add_foreign_key "wiki_assets", "wiki_pages"
|
||||||
add_foreign_key "wiki_pages", "tag_names"
|
add_foreign_key "wiki_pages", "tag_names"
|
||||||
add_foreign_key "wiki_pages", "users", column: "created_user_id"
|
add_foreign_key "wiki_pages", "users", column: "created_user_id"
|
||||||
add_foreign_key "wiki_pages", "users", column: "updated_user_id"
|
add_foreign_key "wiki_pages", "users", column: "updated_user_id"
|
||||||
|
|||||||
@@ -124,7 +124,7 @@ namespace :nico do
|
|||||||
|
|
||||||
datum['tags'].each do |raw|
|
datum['tags'].each do |raw|
|
||||||
name = TagNameSanitisationRule.sanitise("nico:#{ raw }")
|
name = TagNameSanitisationRule.sanitise("nico:#{ raw }")
|
||||||
tag = Tag.find_or_create_by_tag_name!(name, category: :nico)
|
tag = Tag.find_or_create_by_tag_name!(Locale.nipponese, name, category: :nico)
|
||||||
|
|
||||||
event_type = tag.nico_tag_versions.exists? ? :update : :create
|
event_type = tag.nico_tag_versions.exists? ? :update : :create
|
||||||
NicoTagVersionRecorder.record!(tag:, event_type:, created_by_user: nil)
|
NicoTagVersionRecorder.record!(tag:, event_type:, created_by_user: nil)
|
||||||
|
|||||||
新しいイシューから参照
ユーザーをブロックする