多言語化の基盤作り (#55) (#421)

Reviewed-on: #421
Co-authored-by: miteruzo <miteruzo@naver.com>
このコミットはプルリクエスト #421 でマージされました。
このコミットが含まれているのは:
2026-10-03 02:00:09 +09:00
committed by みてるぞ
コミット e6ab941774
91個のファイルの変更、3370行の追加、1223行の削除
+2
ファイルの表示
@@ -92,4 +92,6 @@ class ApplicationController < ActionController::API
value
end
def resolve_locale! = Locale.find_by(code: params[:locale]) || Locale.nipponese
end
+6 -3
ファイルの表示
@@ -1,5 +1,7 @@
class DeerjikistsController < ApplicationController
def show
locale = resolve_locale!
platform = params[:platform].to_s.strip
code = params[:code].to_s.strip
return render_bad_request('platform は必須です.') if platform.blank?
@@ -7,10 +9,10 @@ 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)
render json: DeerjikistRepr.base(deerjikist, language_code: locale.language_code)
else
head :not_found
end
@@ -20,6 +22,7 @@ class DeerjikistsController < ApplicationController
return head :unauthorized unless current_user
return head :forbidden unless current_user.gte_member?
locale = resolve_locale!
platform = params[:platform].to_s.strip
code = params[:code].to_s.strip
tag_id = params[:tag_id].to_i
@@ -32,7 +35,7 @@ class DeerjikistsController < ApplicationController
d.save!
end
render json: DeerjikistRepr.base(deerjikist)
render json: DeerjikistRepr.base(deerjikist, language_code: locale.language_code)
end
def destroy
+2 -2
ファイルの表示
@@ -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
+2 -2
ファイルの表示
@@ -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|
+41 -20
ファイルの表示
@@ -7,6 +7,8 @@ class MaterialsController < ApplicationController
rescue_from MaterialZipExporter::MissingFileError, with: :render_zip_missing_file
def index
locale = resolve_locale!
page = (params[:page].presence || 1).to_i
limit = (params[:limit].presence || 20).to_i
@@ -20,7 +22,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)
@@ -42,7 +44,10 @@ class MaterialsController < ApplicationController
.offset(offset)
.to_a
response = { materials: MaterialRepr.list_many(materials, host: request.base_url),
response = { materials: MaterialRepr.list_many(
materials,
host: request.base_url,
language_code: locale.language_code),
count: }
if filters[:tag_id]
response[:tag_scope] = material_index_tag_scope(filters, tag_graph)
@@ -55,6 +60,8 @@ class MaterialsController < ApplicationController
end
def show
locale = resolve_locale!
material =
Material
.includes(:tag, :material_export_items)
@@ -63,15 +70,17 @@ 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:)
render json: MaterialRepr.base(material, host: request.base_url,
language_code: locale.language_code).merge(wiki_page_body:)
end
def create
return head :unauthorized unless current_user
return head :forbidden unless current_user.gte_member?
locale = resolve_locale!
tag_name_raw = params[:tag].to_s.strip
file = params[:file]
file_sha256 = MaterialFileSha256.from_upload(file)
@@ -89,13 +98,14 @@ class MaterialsController < ApplicationController
begin
Material.transaction do
tag = resolve_material_tag!(tag_name_raw)
tag = resolve_material_tag!(locale, tag_name_raw)
material = Material.new(tag:, url:,
created_by_user: current_user,
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)
@@ -107,7 +117,8 @@ class MaterialsController < ApplicationController
if material
log_thumbnail_generation(material, MaterialThumbnailGenerator.generate!(material))
render json: MaterialRepr.base(material, host: request.base_url), status: :created
render json: MaterialRepr.base(material, host: request.base_url,
language_code: locale.language_code), status: :created
else
render_validation_error material
end
@@ -132,12 +143,14 @@ class MaterialsController < ApplicationController
block = MaterialImportBlockMatcher.match_for_sha256(file_sha256)
return render_material_import_block(block) if block
locale = resolve_locale!
uploaded_blob = build_uploaded_material_blob!(file, file_sha256)
begin
Material.transaction do
MaterialVersionRecorder.ensure_snapshot!(material, created_by_user: current_user)
tag = resolve_material_tag!(tag_name_raw)
tag = resolve_material_tag!(locale, tag_name_raw)
material.assign_attributes(tag:, url:, updated_by_user: current_user)
if uploaded_blob
material.file.attach(uploaded_blob)
@@ -145,7 +158,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)
@@ -157,7 +171,8 @@ class MaterialsController < ApplicationController
log_thumbnail_generation(material, MaterialThumbnailGenerator.generate!(material))
render json: MaterialRepr.base(material, host: request.base_url)
render json: MaterialRepr.base(material, host: request.base_url,
language_code: locale.language_code)
end
def destroy
@@ -236,10 +251,8 @@ class MaterialsController < ApplicationController
nil
end
def resolve_material_tag! tag_name_raw
tag_name = TagName.find_or_create_by!(name: tag_name_raw)
tag = tag_name.tag
tag || Tag.create!(tag_name:, category: :material)
def resolve_material_tag! locale, tag_name_raw
Tag.find_or_create_by_tag_name!(locale, tag_name_raw, category: :material)
end
def material_index_needs_tag_name? filters
@@ -253,7 +266,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
@@ -269,9 +287,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
@@ -323,8 +343,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? }
+20 -7
ファイルの表示
@@ -1,5 +1,7 @@
class NicoTagsController < ApplicationController
def index
locale = resolve_locale!
name = params[:name].presence
linked_tag = params[:linked_tag].presence
link_status = params[:link_status].presence
@@ -24,7 +26,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 +36,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)
@@ -67,7 +70,9 @@ class NicoTagsController < ApplicationController
render json: { tags: tags.map { |tag|
external_tag_json(tag).merge(
recent_post_tag_created_at: tag.recent_post_tag_created_at,
linked_tags: tag.linked_tags.map { |lt| TagRepr.base(lt) })
linked_tags: tag.linked_tags.map { |lt|
TagRepr.base(lt, language_code: locale.language_code)
})
}, count: }
end
@@ -81,6 +86,8 @@ class NicoTagsController < ApplicationController
return head :unauthorized unless current_user
return head :forbidden unless current_user.gte_member?
locale = resolve_locale!
id = params[:id].to_i
tag = ExternalTag.find(id)
@@ -89,10 +96,14 @@ class NicoTagsController < ApplicationController
linked_tags = nil
ApplicationRecord.transaction do
linked_tags = Tag.normalise_tags!(linked_tag_names, with_tagme: false,
with_no_deerjikist: false)
linked_tags = Tag.normalise_tags!(locale, linked_tag_names,
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!
@@ -102,7 +113,9 @@ class NicoTagsController < ApplicationController
created_by_user: current_user)
end
render json: tag.linked_tags.map { |t| TagRepr.base(t) }, status: :ok
render json: tag.linked_tags.map { |t|
TagRepr.base(t, language_code: locale.language_code)
}, status: :ok
rescue Tag::NicoTagNormalisationError
render_validation_error fields: { tags: ['ニコニコ・タグ同士は連携できません.'] }
rescue ActiveRecord::RecordInvalid => e
+70 -46
ファイルの表示
@@ -7,6 +7,8 @@ class PostsController < ApplicationController
end
def index
locale = resolve_locale!
url = params[:url].presence
title = params[:title].presence
original_created_from = params[:original_created_from].presence
@@ -46,12 +48,12 @@ class PostsController < ApplicationController
'COALESCE(pt_max.max_updated_at, posts.updated_at))'
q =
filtered_posts
filtered_posts(locale)
.joins("LEFT JOIN (#{ pt_max_sql }) pt_max ON pt_max.post_id = posts.id")
.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
@@ -90,7 +92,8 @@ class PostsController < ApplicationController
q = q.except(:select, :order)
render json: { posts: posts.map { |post|
PostRepr.base(post).merge(updated_at: post.updated_at_all).tap do |json|
PostRepr.base(post, language_code: locale.language_code)
.merge(updated_at: post.updated_at_all).tap do |json|
json['thumbnail'] =
if post.thumbnail.attached?
rails_storage_proxy_url(post.thumbnail, only_path: false)
@@ -102,17 +105,19 @@ class PostsController < ApplicationController
end
def random
locale = resolve_locale!
post =
filtered_posts
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
return head :not_found unless post
render json: PostRepr.base(post, current_user)
render json: PostRepr.base(post, current_user, language_code: locale.language_code)
end
def metadata
@@ -187,11 +192,13 @@ class PostsController < ApplicationController
end
def show
locale = resolve_locale!
post =
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
@@ -205,18 +212,21 @@ class PostsController < ApplicationController
parent_posts:,
child_posts:,
sibling_posts:,
related:)
.merge(tags: build_tag_tree_for(post))
related:,
language_code: locale.language_code)
.merge(tags: build_tag_tree_for(post, locale.language_code))
end
def create
return head :unauthorized unless current_user
return head :forbidden unless current_user.gte_member?
locale = resolve_locale!
preflight = PostCreatePreflight.new(
attributes: post_create_attributes,
thumbnail: params[:thumbnail],
host: request.base_url).run
host: request.base_url).run(locale)
return render json: dry_run_json(preflight) if bool?(:dry)
if preflight[:existing_post_id].present?
post = Post.new(url: preflight[:url])
@@ -242,10 +252,10 @@ class PostsController < ApplicationController
:post_tag_specs,
:tag_sections,
:normalised_parent_post_ids).symbolize_keys).merge(
thumbnail: params[:thumbnail])).create!
thumbnail: params[:thumbnail])).create!(locale)
post.reload
render json: PostRepr.base(post), status: :created
render json: PostRepr.base(post, language_code: locale.language_code), status: :created
rescue PostCreatePreflight::ValidationFailed => e
render_validation_error fields: e.fields, base: e.base_errors
rescue Tag::NicoTagNormalisationError
@@ -271,13 +281,18 @@ class PostsController < ApplicationController
return head :forbidden unless current_user.gte_member?
return head :unsupported_media_type unless request.content_mime_type == Mime[:multipart_form]
return head :payload_too_large if request.content_length.to_i > MAX_BULK_REQUEST_BYTES
locale = resolve_locale!
posts = parse_bulk_posts_manifest
thumbnails = parse_bulk_thumbnails(posts.length)
result = PostBulkCreator.new(
actor: current_user,
posts:,
thumbnails:,
host: request.base_url).run
host: request.base_url).run(locale)
render json: result
rescue JSON::ParserError
render_bad_request 'posts manifest の JSON が不正です.'
@@ -310,6 +325,7 @@ class PostsController < ApplicationController
base_version_no = parse_base_version_no
return render_bad_request('base_version_no は必須です.') if !(force) && !(base_version_no)
locale = Locale.find_by(code: params[:locale].presence) || Locale.nipponese
title = params[:title].presence
tag_names = params[:tags].to_s.split
original_created_from = params[:original_created_from]
@@ -329,9 +345,10 @@ 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(title:,
incoming_snapshot = post_incoming_snapshot(locale:,
title:,
original_created_from:,
original_created_before:,
tag_names:,
@@ -360,14 +377,14 @@ class PostsController < ApplicationController
end
end
apply_post_snapshot!(post, snapshot_to_apply)
apply_post_snapshot!(locale, post, snapshot_to_apply)
end
return render json: conflict_json, status: :conflict if conflict_json
post.reload
json = PostRepr.base(post, current_user)
json['tags'] = build_tag_tree_for(post)
json = PostRepr.base(post, current_user, language_code: locale.language_code)
json['tags'] = build_tag_tree_for(post, locale.language_code)
render json:, status: :ok
rescue Tag::NicoTagNormalisationError
render_validation_error fields: { tags: ['ニコニコ・タグは直接指定できません.'] }
@@ -385,19 +402,19 @@ class PostsController < ApplicationController
private
def filtered_posts
def filtered_posts locale
tag_names = params[:tags].to_s.split
match_type = params[:match]
if tag_names.present?
filter_posts_by_tags(tag_names, match_type)
filter_posts_by_tags(locale, tag_names, match_type)
else
Post.all
end
end
def filter_posts_by_tags tag_names, match_type
def filter_posts_by_tags locale, tag_names, match_type
literals = tag_names.map do |raw_name|
{ name: TagName.canonicalise(raw_name.sub(/\Anot:/i, '')).first,
{ name: TagName.canonicalise(locale, raw_name.sub(/\Anot:/i, '')).first,
negative: raw_name.downcase.start_with?('not:') }
end
@@ -405,11 +422,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
@@ -419,8 +436,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
@@ -428,11 +445,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 =
@@ -474,7 +491,7 @@ class PostsController < ApplicationController
end
end
def build_tag_tree_for post
def build_tag_tree_for post, language_code = 'ja'
post_tags = post.post_tags.reject { |post_tag| post_tag.tag.deprecated? }
tags = post_tags.map(&:tag)
tag_ids = tags.map(&:id)
@@ -504,7 +521,7 @@ class PostsController < ApplicationController
sections = sections_by_tag_id.fetch(tag_id, [])
if path.include?(tag_id)
return TagRepr.inline(tag).merge(children: [], sections:)
return TagRepr.inline(tag, language_code:).merge(children: [], sections:)
end
if memo.key?(tag_id)
@@ -516,7 +533,7 @@ class PostsController < ApplicationController
children = child_ids.filter_map { |cid| build_node.(cid, new_path) }
memo[tag_id] = TagRepr.inline(tag).merge(children:, sections:)
memo[tag_id] = TagRepr.inline(tag, language_code:).merge(children:, sections:)
end
internal_tags = root_ids.filter_map { |id| build_node.call(id, []) }
@@ -672,40 +689,46 @@ class PostsController < ApplicationController
version.tags_json
.select { _1.key?('tag_id') }
.map { Post.tag_snapshot_literal(_1) }
.compact
.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?
"#{ name }#{ sections.map { Post.section_literal(_1) }.join }"
end
end.compact.sort
end
def post_incoming_snapshot 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:
validate_original_created_values!(original_created_from, original_created_before)
Tag.normalise_tags!(tag_names, with_tagme: false, deny_deprecated: true,
with_sections: true) => { tags:, sections: }
Tag.normalise_tags!(locale, tag_names,
with_tagme: false,
with_no_deerjikist: false,
deny_deprecated: true,
with_sections: true) => { tags:, sections: }
tags = Tag.expand_parent_tags(tags).reject(&:deprecated?)
video_ms = normalise_video_ms(tags, video_ms_param:, duration_param:)
@@ -716,7 +739,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
@@ -840,7 +863,7 @@ class PostsController < ApplicationController
(added_by_current & removed_by_me).present? || (removed_by_current & added_by_me).present?
end
def apply_post_snapshot! post, snapshot
def apply_post_snapshot! locale, post, snapshot
PostVersionRecorder.ensure_snapshot!(post, created_by_user: current_user)
post.update!(title: snapshot[:title],
@@ -848,11 +871,12 @@ class PostsController < ApplicationController
original_created_from: snapshot[:original_created_from],
original_created_before: snapshot[:original_created_before])
Tag.normalise_tags!(snapshot[:tag_names],
Tag.normalise_tags!(locale, snapshot[:tag_names],
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?)
+20 -8
ファイルの表示
@@ -1,5 +1,6 @@
class TagVersionsController < ApplicationController
def index
locale = resolve_locale!
tag_id = params[:id].presence
page = (params[:page].presence || 1).to_i
limit = (params[:limit].presence || 20).to_i
@@ -18,7 +19,8 @@ class TagVersionsController < ApplicationController
SQL
.select('tag_versions.*', 'prev.name AS prev_name', 'prev.category AS prev_category',
'prev.deprecated_at AS prev_deprecated_at',
'prev.aliases AS prev_aliases', 'prev.parent_tag_ids AS prev_parent_tag_ids')
'prev.aliases AS prev_aliases', 'prev.names AS prev_names',
'prev.parent_tag_ids AS prev_parent_tag_ids')
q = q.where('tag_versions.tag_id = ?', tag_id) if tag_id
count = q.except(:select, :order, :limit, :offset).count
@@ -27,18 +29,20 @@ class TagVersionsController < ApplicationController
.limit(limit)
.offset(offset)
render json: { versions: serialise_versions(versions), count: }
render json: { versions: serialise_versions(versions, locale.language_code), count: }
end
private
def serialise_versions rows
def serialise_versions rows, language_code
user_ids = rows.map(&:created_by_user_id).compact.uniq
users_by_id = User.where(id: user_ids).pluck(:id, :name).to_h
rows.map do |row|
cur_aliases = split_values(row.aliases)
prev_aliases = split_values(row.attributes['prev_aliases'])
current_names = names_for_locale(row.names, language_code)
previous_names = names_for_locale(row.attributes['prev_names'], language_code)
cur_aliases = current_names.fetch('aliases', []).map { _1.fetch('name') }
prev_aliases = previous_names.fetch('aliases', []).map { _1.fetch('name') }
cur_parent_tag_ids = split_parent_tag_ids(row.parent_tag_ids)
prev_parent_tag_ids = split_parent_tag_ids(row.attributes['prev_parent_tag_ids'])
@@ -47,21 +51,22 @@ 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)
parent_tags =
build_version_values(cur_parent_tag_ids, prev_parent_tag_ids, key: :tag_id)
.map do |h|
{ tag: TagRepr.base(tags_by_id[h[:tag_id]]),
{ tag: TagRepr.base(tags_by_id[h[:tag_id]], language_code:),
type: h[:type] }
end
{ tag_id: row.tag_id,
version_no: row.version_no,
event_type: row.event_type,
name: { current: row.name, prev: row.attributes['prev_name'] },
names: row.names,
name: { current: current_names['name'], prev: previous_names['name'] },
category: { current: row.category, prev: row.attributes['prev_category'] },
deprecated_at: { current: row.deprecated_at&.iso8601,
prev: row.attributes['prev_deprecated_at']&.iso8601 },
@@ -91,5 +96,12 @@ class TagVersionsController < ApplicationController
def split_values(values) = values.to_s.split(/\s+/).reject(&:blank?)
def names_for_locale names, language_code
values = names.is_a?(String) ? JSON.parse(names) : names
values&.fetch(language_code, {}) || {}
rescue JSON::ParserError
{}
end
def split_parent_tag_ids(values) = split_values(values).map(&:to_i)
end
+212 -118
ファイルの表示
@@ -5,6 +5,8 @@ require 'set'
class TagsController < ApplicationController
def index
locale = resolve_locale!
post_id = params[:post]
name = params[:name].presence
@@ -36,9 +38,14 @@ class TagsController < ApplicationController
tags =
if post_id.present?
Tag.joins(:posts, :tag_name).where(posts: { id: post_id })
Tag
.joins(:posts, :tag_names)
.where(tag_names: { language_code: locale.language_code, primary_flg: true },
posts: { id: post_id })
else
Tag.joins(:tag_name)
Tag
.joins(:tag_names)
.where(tag_names: { language_code: locale.language_code, primary_flg: true })
end
external_tags =
@@ -167,9 +174,10 @@ class TagsController < ApplicationController
tags_by_id =
Tag
.joins(:tag_name)
.includes(:tag_name, :materials, tag_name: :wiki_page)
.where(id: tag_ids)
.joins(:tag_names)
.includes(:tag_names, :materials, tag_names: :wiki_page)
.where(tag_names: { language_code: locale.language_code, primary_flg: true },
id: tag_ids)
.index_by(&:id)
external_tags_by_id =
ExternalTag
@@ -178,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
@@ -190,7 +198,8 @@ class TagsController < ApplicationController
parent_tag_id = nil if parent_tag_id <= 0
material_filter = material_filter_param(default: 'any')
graph = build_with_depth_graph(material_filter)
locale = resolve_locale!
graph = build_with_depth_graph(material_filter, locale.language_code)
tag_ids =
if parent_tag_id
@@ -205,6 +214,8 @@ class TagsController < ApplicationController
end
def autocomplete
locale = resolve_locale!
q = params[:q].to_s.strip.sub(/\Anot:/i, '')
prefix = "#{ ActiveRecord::Base.sanitize_sql_like(q) }%"
@@ -213,35 +224,36 @@ class TagsController < ApplicationController
alias_rows =
TagName
.where(language_code: locale.language_code, primary_flg: false)
.where('name LIKE ?', prefix)
.where.not(canonical_id: nil)
.pluck(:canonical_id, :name)
.pluck(:tag_id, :name)
matched_alias_by_tag_name_id = { }
canonical_ids = []
alias_rows.each do |canonical_id, alias_name|
canonical_ids << canonical_id
matched_alias_by_tag_name_id[canonical_id] ||= alias_name
matched_alias_by_tag_id = { }
tag_ids = []
alias_rows.each do |tag_id, alias_name|
tag_ids << tag_id
matched_alias_by_tag_id[tag_id] ||= alias_name
end
base =
Tag
.joins(:tag_name)
.includes(:tag_name, :materials, tag_name: :wiki_page)
.where(deprecated_at: nil)
.joins(:tag_names)
.includes(:tag_names, :materials, tag_names: :wiki_page)
.where(tag_names: { language_code: locale.language_code, primary_flg: true },
deprecated_at: nil)
base = base.where('tags.post_count > 0') if present_only
canonical_hit = base.where('tag_names.name LIKE ?', prefix)
internal_tags = canonical_hit.or(base.where(tag_name_id: canonical_ids.uniq))
internal_tags = canonical_hit.or(base.where(id: tag_ids.uniq))
internal_rows =
internal_tags
.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
@@ -257,20 +269,23 @@ 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
end
def show
locale = resolve_locale!
tag =
Tag
.joins(:tag_name)
.includes(:tag_name, :materials, tag_name: :wiki_page)
.find_by(id: params[:id])
return render json: TagRepr.base(tag) if tag
.joins(:tag_names)
.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, 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
@@ -282,12 +297,14 @@ class TagsController < ApplicationController
name = params[:name].to_s.strip
return render_bad_request('name は必須です.') if name.blank?
locale = resolve_locale!
tag =
Tag
.joins(:tag_name)
.includes(:tag_name, :materials, tag_name: :wiki_page)
.find_by(tag_names: { name: })
return render json: TagRepr.base(tag) if tag
.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, language_code: locale.language_code) if tag
platform, external_name = name.split(':', 2)
return head :not_found unless external_name
@@ -299,35 +316,52 @@ class TagsController < ApplicationController
end
def deerjikists
tag = Tag.joins(:tag_name)
.includes(:tag_name, tag_name: :wiki_page)
.find_by(id: params[:id])
locale = resolve_locale!
tag =
Tag.joins(:tag_names)
.includes(:tag_names, tag_names: :wiki_page)
.find_by(id: params[:id],
tag_names: { language_code: locale.language_code, primary_flg: true })
return head :not_found unless tag
render json: { tag: TagRepr.base(tag),
deerjikists: DeerjikistRepr.many(tag.deerjikists) }
render json: { tag: TagRepr.base(tag, language_code: locale.language_code),
deerjikists: DeerjikistRepr.many(
tag.deerjikists,
language_code: locale.language_code) }
end
def deerjikists_by_name
name = params[:name].to_s.strip
return render_bad_request('name は必須です.') if name.blank?
tag = Tag.joins(:tag_name)
.includes(:tag_name, tag_name: :wiki_page)
.find_by(tag_names: { name: })
locale = resolve_locale!
tag =
Tag
.joins(:tag_names)
.includes(:tag_names, tag_names: :wiki_page)
.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),
deerjikists: DeerjikistRepr.many(tag.deerjikists) }
render json: { tag: TagRepr.base(tag, language_code: locale.language_code),
deerjikists: DeerjikistRepr.many(
tag.deerjikists,
language_code: locale.language_code) }
end
def update_deerjikists
return head :unauthorized unless current_user
return head :forbidden unless current_user.gte_member?
tag = Tag.joins(:tag_name)
.includes(:tag_name, tag_name: :wiki_page)
.find_by(id: params[:id])
locale = resolve_locale!
tag =
Tag
.joins(:tag_names)
.includes(:tag_names, tag_names: :wiki_page)
.find_by(id: params[:id],
tag_names: { language_code: locale.language_code, primary_flg: true })
return head :not_found unless tag
rows = normalise_deerjikist_rows(tag)
@@ -346,7 +380,7 @@ class TagsController < ApplicationController
row_indexes_by_key.key?([deerjikist.platform, deerjikist.code])
}
render_deerjikist_conflicts(requested_deerjikists, row_indexes_by_key, tag)
render_deerjikist_conflicts(locale, requested_deerjikists, row_indexes_by_key, tag)
raise ActiveRecord::Rollback if performed?
requested_keys_set = requested_keys.to_set
@@ -367,7 +401,7 @@ class TagsController < ApplicationController
render_deerjikist_form_record_invalid(deerjikist, row_index) unless deerjikist.save
rescue ActiveRecord::RecordNotUnique
conflicts = lock_deerjikists_for_tag_update(tag.id, [[platform, code]])
render_deerjikist_conflicts(conflicts, row_indexes_by_key, tag)
render_deerjikist_conflicts(locale, conflicts, row_indexes_by_key, tag)
end
raise ActiveRecord::Rollback if performed?
end
@@ -375,22 +409,28 @@ class TagsController < ApplicationController
return if performed?
render json: DeerjikistRepr.many(tag.reload.deerjikists)
render json: DeerjikistRepr.many(tag.reload.deerjikists,
language_code: locale.language_code)
end
def materials_by_name
name = params[:name].to_s.strip
return render_bad_request('name は必須です.') if name.blank?
locale = resolve_locale!
material_filter = material_filter_param(default: 'any')
tag = Tag.joins(:tag_name)
.includes(:tag_name, :materials, tag_name: :wiki_page)
.find_by(tag_names: { name: })
tag =
Tag
.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 head :not_found unless tag
graph = build_with_depth_graph(material_filter)
graph = build_with_depth_graph(material_filter, locale.language_code)
render json: build_tag_children(tag, graph:)
render json: build_tag_children(tag, graph:, language_code: locale.language_code)
end
def update_all
@@ -406,7 +446,9 @@ class TagsController < ApplicationController
return render_unprocessable_entity('カテゴリは必須です.', field: :category) if category.blank?
return render_unprocessable_entity '廃止状態は必須です.', field: :deprecated unless params.key?(:deprecated)
return unless validate_tag_rename(tag, name)
locale = resolve_locale!
return unless validate_tag_rename(locale, tag, name)
alias_names = params[:aliases].to_s.split.uniq
parent_names = params[:parent_tags].to_s.split.uniq
@@ -417,24 +459,25 @@ 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:)
else
tag.update!(category:, deprecated_at: deprecated ? Time.current : nil)
end
rename_tag_name!(tag, name) if name_changed
rename_tag_name!(locale, tag, name) if name_changed
alias_names << old_name if name_changed
alias_names << old_name if name_changed && old_name.present?
alias_names.delete(name)
update_aliases!(tag, alias_names)
update_parent_tags!(tag, parent_names)
update_aliases!(locale, tag, alias_names)
update_parent_tags!(locale, tag, parent_names)
tag.reload
@@ -442,17 +485,20 @@ 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
return head :unauthorized unless current_user
return head :forbidden unless current_user.gte_member?
locale = resolve_locale!
name = params[:name].presence
category = params[:category].presence
deprecated_given = params.key?(:deprecated)
@@ -460,20 +506,21 @@ class TagsController < ApplicationController
tag = Tag.find(params[:id])
return unless validate_tag_rename(tag, name)
return unless validate_tag_rename(locale, tag, name)
if category.present? && category == 'nico'
return render_unprocessable_entity 'ニコタグは変更できません.', field: :category
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)
@@ -485,11 +532,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
@@ -501,7 +549,7 @@ class TagsController < ApplicationController
value
end
def build_with_depth_graph material_filter
def build_with_depth_graph material_filter, language_code
children_by_parent_id = Hash.new { |h, k| h[k] = [] }
parent_ids_by_child_id = Hash.new { |h, k| h[k] = [] }
@@ -516,10 +564,13 @@ class TagsController < ApplicationController
material_tag_ids = Material.unscoped.kept.where.not(tag_id: nil).distinct.pluck(:tag_id).to_set
tags_by_id = Tag.joins(:tag_name)
.where(id: tag_ids)
.pluck('tags.id', 'tag_names.name', 'tags.category', 'tags.deprecated_at')
.each_with_object({ }) do |(id, name, category, deprecated_at), h|
tags_by_id =
Tag
.joins(:tag_names)
.where(id: tag_ids,
tag_names: { language_code:, primary_flg: true })
.pluck('tags.id', 'tag_names.name', 'tags.category', 'tags.deprecated_at')
.each_with_object({ }) do |(id, name, category, deprecated_at), h|
h[id] = { name:, category:, deprecated: deprecated_at.present?,
has_material: material_tag_ids.include?(id) }
end
@@ -651,29 +702,33 @@ 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))
material: material && MaterialRepr.base(
material,
host: request.base_url,
language_code:))
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!(
@@ -682,30 +737,43 @@ class TagsController < ApplicationController
created_by_user:)
end
def validate_tag_rename tag, name
return true if name.blank? || name == tag.name
def validate_tag_rename locale, 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
target_tag_name = TagName.find_by(name:)
return true if target_tag_name.nil?
return true if target_tag_name.canonical_id?
target_tag_name = TagName.find_by(language_code: locale.language_code, name:)
return true unless target_tag_name&.primary_flg
render_unprocessable_entity 'その名前は既に使はれてゐます.', field: :name
false
end
def rename_tag_name! tag, name
return if name == tag.name
def rename_tag_name! locale, tag, name
return if name == tag.name(locale.language_code)
current_tag_name = tag.tag_name
target_tag_name = TagName.find_by(name:)
current_tag_name = tag.tag_name(locale.language_code)
target_tag_name = TagName.find_by(language_code: locale.language_code, name:)
if target_tag_name.nil?
current_tag_name.update!(name:)
unless target_tag_name
if current_tag_name
current_tag_name.update!(name:, auto_generated: false)
else
current_tag_name = TagName.create!(
tag:,
language_code: locale.language_code,
script_code: locale.script_code,
name:,
primary_flg: true)
tag.association(:tag_names).reset
end
return
end
@@ -713,72 +781,96 @@ 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: nil)
current_tag_name.wiki_page&.update!(tag_name_id: promoted_tag_name.id)
current_tag_name.association(:wiki_page).reset
TagName.where(canonical_id: current_tag_name.id)
current_tag_name.update!(canonical_id: promoted_tag_name.id,
primary_flg: false, auto_generated: false)
promoted_tag_name.update!(tag:, canonical_id: nil, primary_flg: true, auto_generated: false)
TagName.where(tag:,
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: promoted_tag_name)
alias_tag_name.update!(canonical_id: promoted_tag_name.id, primary_flg: false)
end
current_tag_name.wiki_page&.update!(tag_name: promoted_tag_name)
tag.update!(tag_name: promoted_tag_name)
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: promoted_tag_name)
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 = TagName.find_by!(tag:,
language_code: locale.language_code,
primary_flg: true)
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)
if alias_tag_name&.primary? && alias_tag_name.tag_id && alias_tag_name.tag_id != tag.id
alias_tag_name.errors.add(:name, 'その名前は既に使はれてゐます.')
raise ActiveRecord::RecordInvalid, alias_tag_name
end
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: 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: tag.tag_name)
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, auto_generated: 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
def update_parent_tags! tag, parent_names
parent_tags = Tag.normalise_tags!(parent_names, with_tagme: false,
with_no_deerjikist: false)
def update_parent_tags! locale, tag, parent_names
parent_tags = Tag.normalise_tags!(locale, parent_names,
with_tagme: false,
with_no_deerjikist: false)
old_parent_tags = tag.parents.to_a
@@ -851,15 +943,17 @@ class TagsController < ApplicationController
.to_a
end
def render_deerjikist_conflicts deerjikists, row_indexes_by_key, tag
def render_deerjikist_conflicts locale, deerjikists, row_indexes_by_key, tag
conflicts = deerjikists.filter { |deerjikist| deerjikist.tag_id != tag.id }
return if conflicts.empty?
tag_names_by_id = Tag
.joins(:tag_name)
.where(id: conflicts.map(&:tag_id).uniq)
.pluck('tags.id', 'tag_names.name')
.to_h
tag_names_by_id =
Tag
.joins(:tag_names)
.where(tag_names: { language_code: locale.language_code, primary_flg: true },
id: conflicts.map(&:tag_id).uniq)
.pluck('tags.id', 'tag_names.name')
.to_h
fields = { }
conflicts.each do |deerjikist|
+2 -2
ファイルの表示
@@ -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 }
}
+5 -1
ファイルの表示
@@ -94,7 +94,11 @@ class WikiPagesController < ApplicationController
return render_unprocessable_entity('タイトルは必須です.', field: :title) if title.blank?
return render_unprocessable_entity('本文は必須です.', field: :body) if body.blank?
tag_name = TagName.find_or_create_by!(name: title)
tag_name = TagName.find_or_create_by!(language_code: 'ja', name: title) do |name|
name.script_code = 'Jpan'
name.primary_flg = true
name.auto_generated = false
end
page =
Wiki::Commit.create_content!(