このコミットが含まれているのは:
2026-10-20 20:29:18 +09:00
コミット 7afb96d226
21個のファイルの変更、617行の追加、66行の削除
+2 -1
ファイルの表示
@@ -255,7 +255,8 @@ class MaterialsController < ApplicationController
end
def resolve_material_tag! locale, tag_name_raw
Tag.find_or_create_by_tag_name!(locale, tag_name_raw, category: :material)
Tag.find_or_create_by_tag_name!(locale, tag_name_raw, category: :material,
created_by_user: current_user)
end
def material_index_needs_tag_name? filters
+19 -5
ファイルの表示
@@ -98,7 +98,8 @@ class NicoTagsController < ApplicationController
ApplicationRecord.transaction do
linked_tags = Tag.normalise_tags!(locale, linked_tag_names,
with_tagme: false,
with_no_deerjikist: false)
with_no_deerjikist: false,
created_by_user: current_user)
TagVersioning.record_tag_snapshots!(
linked_tags,
@@ -140,10 +141,23 @@ class NicoTagsController < ApplicationController
end
def render_nico_tag_form_record_invalid record
if record.is_a?(TagName) || record.is_a?(Tag)
render_validation_error fields: { tags: record.errors.full_messages.map { |message|
"タグ名 “#{ record.name }”: #{ message }"
} }
names =
case record
when TagName
[record]
when Tag
record.tag_names.to_a
else
[]
end
messages = names.flat_map do |tag_name|
tag_name.errors.full_messages.map do |message|
"タグ名 “#{ tag_name.name }”: #{ message }"
end
end
if messages.any?
render_validation_error fields: { tags: messages }
else
render_validation_error record
end
+4 -2
ファイルの表示
@@ -818,7 +818,8 @@ class PostsController < ApplicationController
with_tagme: false,
with_no_deerjikist: false,
deny_deprecated: true,
with_sections: true) => { tags:, sections: }
with_sections: true,
created_by_user: current_user) => { tags:, sections: }
tags = Tag.expand_parent_tags(tags).reject(&:deprecated?)
video_ms = normalise_video_ms(tags, video_ms_param:, duration_param:)
@@ -964,7 +965,8 @@ class PostsController < ApplicationController
Tag.normalise_tags!(locale, snapshot[:tag_names],
with_tagme: false,
deny_deprecated: true,
with_sections: true) => { tags:, sections: }
with_sections: true,
created_by_user: current_user) => { tags:, sections: }
TagVersioning.record_tag_snapshots!(tags, created_by_user: current_user,
language_code: locale.language_code)
+57
ファイルの表示
@@ -0,0 +1,57 @@
class SitemapEntriesController < ApplicationController
PAGE_SIZE = 1_000
RESOURCES = [
'posts', 'tags', 'deerjikists', 'materials',
'descriptions', 'tag_groups', 'theatres'].freeze
def index
locale = resolve_locale!
resources = RESOURCES.map { |resource| { resource:, count: entries(resource, locale).count } }
render json: { resources:, page_size: PAGE_SIZE }
end
def show
locale = resolve_locale!
resource = params[:resource]
return head :not_found unless RESOURCES.include?(resource)
page = Integer(params.fetch(:page, '1'), exception: false)
return head :bad_request unless page && page.positive?
scope = entries(resource, locale)
return head :not_found if page > [(scope.count.to_f / PAGE_SIZE).ceil, 1].max
ids = scope.order(:id).offset((page - 1) * PAGE_SIZE).limit(PAGE_SIZE).pluck(:id)
render json: { ids: }
end
private
def entries resource, locale
named_tags = TagName.where(language_code: locale.language_code, primary_flg: true)
.select(:tag_id)
case resource
when 'posts'
Post.all
when 'tags'
Tag.where(id: named_tags)
when 'deerjikists'
Tag.where(id: named_tags).where(id: Deerjikist.select(:tag_id))
when 'materials'
Material.all
when 'descriptions'
TagDescription.where(language_code: locale.language_code, tag_id: named_tags)
.where.not(body: [nil, ''])
.where(TagDescriptionVersion
.where('tag_description_versions.tag_id = tag_descriptions.tag_id')
.where('tag_description_versions.language_code = tag_descriptions.language_code')
.where('tag_description_versions.version_no = tag_descriptions.version_no')
.arel.exists)
when 'tag_groups'
TagGroup.joins(:versions)
.where('tag_group_versions.version_no = tag_groups.version_no')
when 'theatres'
Theatre.kept
end
end
end
+2 -1
ファイルの表示
@@ -844,7 +844,8 @@ class TagsController < ApplicationController
def update_parent_tags! locale, tag, parent_names
parent_tags = Tag.normalise_tags!(locale, parent_names,
with_tagme: false,
with_no_deerjikist: false)
with_no_deerjikist: false,
created_by_user: current_user)
old_parent_tags = tag.parents.to_a
+9 -8
ファイルの表示
@@ -142,7 +142,8 @@ class Tag < ApplicationRecord
with_tagme: true,
with_no_deerjikist: true,
deny_deprecated: false,
with_sections: false
with_sections: false,
created_by_user: nil
if tag_names.any? { |n| n.downcase.start_with?('nico:') }
raise NicoTagNormalisationError
end
@@ -171,7 +172,8 @@ class Tag < ApplicationRecord
name = TagName.canonicalise(locale, name).first
find_or_create_by_tag_name!(locale, name, category: (cat || :general)).tap do |tag|
find_or_create_by_tag_name!(locale, name, category: (cat || :general),
created_by_user:).tap do |tag|
if deny_deprecated && tag.deprecated?
raise DeprecatedTagNormalisationError, [tag.name(locale.language_code)]
end
@@ -259,7 +261,7 @@ class Tag < ApplicationRecord
[left_end_ms, right_end_ms].max
end
def find_or_create_by_tag_name! locale, name, category:
def find_or_create_by_tag_name! locale, name, category:, created_by_user: nil
language_code = locale.language_code
name = name.to_s.strip
@@ -268,11 +270,10 @@ class Tag < ApplicationRecord
tn = TagName.lock.find_by(language_code:, name:)
next tn.tag if tn
tag = Tag.create!(category:)
TagName.create!(tag:, language_code:, name:,
script_code: locale.script_code, primary_flg: true,
auto_generated: false)
TagNameCompletion.for_tag!(tag)
tag = Tag.new(category:)
tag.tag_names.build(language_code:, name:, script_code: locale.script_code,
primary_flg: true, auto_generated: false)
TagNameCompletion.for_tag!(tag, created_by_user:)
tag.association(:tag_names).reset
tag
+1 -1
ファイルの表示
@@ -105,7 +105,7 @@ class PostCreator
category = spec[:category] || spec['category']
next if name.blank? || category.blank?
tag = Tag.find_or_create_by_tag_name!(locale, name, category:)
tag = Tag.find_or_create_by_tag_name!(locale, name, category:, created_by_user: @actor)
tag.update!(category:) if tag.category.to_sym != category.to_sym
tags[name] ||= tag
end.values
+11 -6
ファイルの表示
@@ -11,13 +11,14 @@ class TagNameCompletion
end
Tag.where(id: certified_names.keys).lock.find_each(order: :asc) do |tag|
for_tag!(tag, locales: [locale],
certified_names: { locale.language_code => certified_names.fetch(tag.id) })
certified_names: { locale.language_code => certified_names.fetch(tag.id) },
created_by_user: nil)
end
named_tags =
TagName.where(language_code: locale.language_code, primary_flg: true)
.select(:tag_id)
Tag.where.not(id: named_tags).lock.find_each(order: :asc) do |tag|
for_tag!(tag, locales: [locale])
for_tag!(tag, locales: [locale], created_by_user: nil)
end
true
end
@@ -26,12 +27,15 @@ class TagNameCompletion
end
end
def for_tag! tag, locales: nil, certified_names: { }
def for_tag! tag, locales: nil, certified_names: { }, created_by_user: nil
locales ||=
Locale.where(deprecated_at: nil)
.order(:language_code, :created_at, :script_code).lock
Tag.transaction do
SharedResourceIdAllocator.lock_space!(Tag, 'tags')
# Creation includes every language in its first snapshot.
creating = tag.new_record?
tag.save! if creating
completed = tag.with_lock do
primary_names = tag.tag_names.where(primary_flg: true).lock.index_by(&:language_code)
certified_names.each do |language, name|
@@ -46,9 +50,9 @@ class TagNameCompletion
missing_locales = locales.to_a.uniq(&:language_code).reject { |locale|
primary_names.key?(locale.language_code)
}
next true if missing_locales.empty?
next true if missing_locales.empty? && !creating
TagVersioning.ensure_snapshot!(tag, created_by_user: nil)
TagVersioning.ensure_snapshot!(tag, created_by_user:) unless creating
missing_locales.each do |locale|
primary_names[locale.language_code] =
if certified_names.key?(locale.language_code)
@@ -60,7 +64,8 @@ class TagNameCompletion
end
end
tag.association(:tag_names).reset
version = TagVersioning.record!(tag, event_type: :update, created_by_user: nil)
event_type = creating ? :create : :update
version = TagVersioning.record!(tag, event_type:, created_by_user:)
unless version&.persisted?
raise ActiveRecord::RecordNotSaved, 'Tag version was not persisted'
end