このコミットが含まれているのは:
@@ -1,14 +1,18 @@
|
|||||||
class TagDescriptionsController < ApplicationController
|
class TagDescriptionsController < ApplicationController
|
||||||
def show
|
def show
|
||||||
description = TagDescription.find_by(tag_id: params[:id], language_code: 'ja')
|
locale = resolve_locale!
|
||||||
|
description = TagDescription.find_by(tag_id: params[:id], language_code: locale.language_code)
|
||||||
return head :not_found unless description
|
return head :not_found unless description
|
||||||
|
|
||||||
render json: representation(description)
|
render json: representation(description)
|
||||||
end
|
end
|
||||||
|
|
||||||
def show_by_title
|
def show_by_title
|
||||||
tag_name = TagName.find_by(language_code: 'ja', name: params[:name].to_s.strip)
|
locale = resolve_locale!
|
||||||
description = tag_name&.tag && TagDescription.find_by(tag: tag_name.tag, language_code: 'ja')
|
tag_name = TagName.find_by(
|
||||||
|
language_code: locale.language_code, name: params[:name].to_s.strip)
|
||||||
|
description = tag_name&.tag && TagDescription.find_by(
|
||||||
|
tag: tag_name.tag, language_code: locale.language_code)
|
||||||
return head :not_found unless description
|
return head :not_found unless description
|
||||||
|
|
||||||
render json: representation(description)
|
render json: representation(description)
|
||||||
@@ -21,18 +25,19 @@ class TagDescriptionsController < ApplicationController
|
|||||||
body = params[:body].to_s
|
body = params[:body].to_s
|
||||||
return render_unprocessable_entity('本文は必須です.', field: :body) if body.blank?
|
return render_unprocessable_entity('本文は必須です.', field: :body) if body.blank?
|
||||||
|
|
||||||
|
locale = resolve_locale!
|
||||||
tag = Tag.find_by(id: params[:id])
|
tag = Tag.find_by(id: params[:id])
|
||||||
return head :not_found unless tag
|
return head :not_found unless tag
|
||||||
|
|
||||||
description = TagDescription.find_by(tag:, language_code: 'ja')
|
description = TagDescription.find_by(tag:, language_code: locale.language_code)
|
||||||
|
|
||||||
if description
|
if description
|
||||||
TagDescriptionOperation.update!(tag:, body:, updated_by_user: current_user)
|
TagDescriptionOperation.update!(locale, tag:, body:, updated_by_user: current_user)
|
||||||
description.reload
|
description.reload
|
||||||
render json: representation(description)
|
render json: representation(description)
|
||||||
else
|
else
|
||||||
TagDescriptionOperation.create!(tag:, body:, created_by_user: current_user)
|
TagDescriptionOperation.create!(locale, tag:, body:, created_by_user: current_user)
|
||||||
description = TagDescription.find_by!(tag:, language_code: 'ja')
|
description = TagDescription.find_by!(tag:, language_code: locale.language_code)
|
||||||
render json: representation(description), status: :created
|
render json: representation(description), status: :created
|
||||||
end
|
end
|
||||||
rescue ActiveRecord::RecordInvalid => e
|
rescue ActiveRecord::RecordInvalid => e
|
||||||
|
|||||||
@@ -1,33 +1,37 @@
|
|||||||
class TagGroupsController < ApplicationController
|
class TagGroupsController < ApplicationController
|
||||||
def index
|
def index
|
||||||
|
locale = resolve_locale!
|
||||||
groups = TagGroup.includes(:created_by_user, :updated_by_user).order(:id)
|
groups = TagGroup.includes(:created_by_user, :updated_by_user).order(:id)
|
||||||
render json: TagGroupRepr.many(groups.to_a)
|
render json: TagGroupRepr.many(locale, groups.to_a)
|
||||||
end
|
end
|
||||||
|
|
||||||
def show
|
def show
|
||||||
|
locale = resolve_locale!
|
||||||
group = TagGroup.includes(:created_by_user, :updated_by_user).find_by(id: params[:id])
|
group = TagGroup.includes(:created_by_user, :updated_by_user).find_by(id: params[:id])
|
||||||
return head :not_found unless group
|
return head :not_found unless group
|
||||||
|
|
||||||
render json: TagGroupRepr.one(group)
|
render json: TagGroupRepr.one(locale, group)
|
||||||
end
|
end
|
||||||
|
|
||||||
def create
|
def create
|
||||||
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?
|
||||||
|
|
||||||
group = TagGroupOperation.create!(**write_attributes, actor: current_user)
|
locale = resolve_locale!
|
||||||
render json: TagGroupRepr.one(group), status: :created
|
group = TagGroupOperation.create!(locale, **write_attributes, actor: current_user)
|
||||||
|
render json: TagGroupRepr.one(locale, group), status: :created
|
||||||
end
|
end
|
||||||
|
|
||||||
def update
|
def update
|
||||||
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!
|
||||||
group = TagGroup.find_by(id: params[:id])
|
group = TagGroup.find_by(id: params[:id])
|
||||||
return head :not_found unless group
|
return head :not_found unless group
|
||||||
|
|
||||||
TagGroupOperation.update!(group:, **write_attributes, actor: current_user)
|
TagGroupOperation.update!(locale, group:, **write_attributes, actor: current_user)
|
||||||
render json: TagGroupRepr.one(group.reload)
|
render json: TagGroupRepr.one(locale, group.reload)
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|||||||
@@ -4,9 +4,12 @@ class WikiPagesController < ApplicationController
|
|||||||
rescue_from TagDescriptionOperation::Conflict, with: :render_wiki_conflict
|
rescue_from TagDescriptionOperation::Conflict, with: :render_wiki_conflict
|
||||||
|
|
||||||
def index
|
def index
|
||||||
|
locale = resolve_locale!
|
||||||
|
|
||||||
title = params[:title].to_s.strip
|
title = params[:title].to_s.strip
|
||||||
descriptions =
|
descriptions =
|
||||||
TagDescription.where(language_code: 'ja')
|
TagDescription
|
||||||
|
.where(language_code: locale.language_code)
|
||||||
.includes(tag: :tag_names)
|
.includes(tag: :tag_names)
|
||||||
|
|
||||||
descriptions = descriptions.order(updated_at: :desc, id: :asc)
|
descriptions = descriptions.order(updated_at: :desc, id: :asc)
|
||||||
@@ -15,13 +18,14 @@ class WikiPagesController < ApplicationController
|
|||||||
pattern = "%#{ ApplicationRecord.sanitize_sql_like(title) }%"
|
pattern = "%#{ ApplicationRecord.sanitize_sql_like(title) }%"
|
||||||
descriptions =
|
descriptions =
|
||||||
descriptions.joins(tag: :tag_names)
|
descriptions.joins(tag: :tag_names)
|
||||||
.where(tag_names: { language_code: 'ja', primary_flg: true })
|
.where(tag_names: { language_code: locale.language_code, primary_flg: true })
|
||||||
.where('tag_names.name LIKE ?', pattern).limit(20)
|
.where('tag_names.name LIKE ?', pattern).limit(20)
|
||||||
tag_groups = tag_groups.where(
|
tag_groups = tag_groups.where(
|
||||||
'CONCAT(?, name) LIKE ?', TagGroupRepr::PREFIX, pattern).limit(20)
|
'CONCAT(?, name) LIKE ? OR CONCAT(?, name) LIKE ?',
|
||||||
|
TagGroupRepr::PREFIX, pattern, 'tag_group:', pattern).limit(20)
|
||||||
end
|
end
|
||||||
|
|
||||||
json = descriptions.map { |description| WikiPageRepr.tag_description(description) }
|
json = descriptions.map { |description| WikiPageRepr.tag_description(locale, description) }
|
||||||
json.concat(tag_groups.map { WikiPageRepr.tag_group(_1) })
|
json.concat(tag_groups.map { WikiPageRepr.tag_group(_1) })
|
||||||
json.sort_by! do |row|
|
json.sort_by! do |row|
|
||||||
[-row['updated_at'].to_f, row.fetch('resource_type'), row.fetch('id')]
|
[-row['updated_at'].to_f, row.fetch('resource_type'), row.fetch('id')]
|
||||||
@@ -31,47 +35,53 @@ class WikiPagesController < ApplicationController
|
|||||||
end
|
end
|
||||||
|
|
||||||
def show
|
def show
|
||||||
tag_description = TagDescription.find_by(id: params[:id])
|
locale = resolve_locale!
|
||||||
|
tag_description = TagDescription.find_by(id: params[:id], language_code: locale.language_code)
|
||||||
|
|
||||||
return render_wiki_page_by_tag_description tag_description if tag_description
|
return render_wiki_page_by_tag_description locale, tag_description if tag_description
|
||||||
|
|
||||||
tag_group = TagGroup.find_by(id: params[:id])
|
tag_group = TagGroup.find_by(id: params[:id])
|
||||||
return render_tag_group tag_group if tag_group
|
return render_tag_group locale, tag_group if tag_group
|
||||||
|
|
||||||
head :not_found
|
head :not_found
|
||||||
end
|
end
|
||||||
|
|
||||||
def show_by_title
|
def show_by_title
|
||||||
|
locale = resolve_locale!
|
||||||
title = params[:title].to_s.strip
|
title = params[:title].to_s.strip
|
||||||
|
|
||||||
if title.start_with?(TagGroupRepr::PREFIX)
|
if (name = TagGroupRepr.name_from_title(title))
|
||||||
name = title.delete_prefix(TagGroupRepr::PREFIX)
|
|
||||||
tag_group = TagGroup.find_by(name:)
|
tag_group = TagGroup.find_by(name:)
|
||||||
return render_tag_group tag_group if tag_group
|
return render_tag_group locale, tag_group if tag_group
|
||||||
return head :not_found
|
return head :not_found
|
||||||
end
|
end
|
||||||
|
|
||||||
tag_description = tag_description_by_title(title)
|
tag_description = tag_description_by_title(locale, title)
|
||||||
|
|
||||||
return render_wiki_page_by_tag_description tag_description if tag_description
|
return render_wiki_page_by_tag_description locale, tag_description if tag_description
|
||||||
|
|
||||||
head :not_found
|
head :not_found
|
||||||
end
|
end
|
||||||
|
|
||||||
def exists
|
def exists
|
||||||
return head :no_content if TagDescription.exists?(id: params[:id])
|
locale = resolve_locale!
|
||||||
|
if TagDescription.exists?(id: params[:id], language_code: locale.language_code)
|
||||||
|
return head :no_content
|
||||||
|
end
|
||||||
return head :no_content if TagGroup.exists?(id: params[:id])
|
return head :no_content if TagGroup.exists?(id: params[:id])
|
||||||
|
|
||||||
head :not_found
|
head :not_found
|
||||||
end
|
end
|
||||||
|
|
||||||
def exists_by_title
|
def exists_by_title
|
||||||
|
locale = resolve_locale!
|
||||||
title = params[:title].to_s.strip
|
title = params[:title].to_s.strip
|
||||||
if title.start_with?(TagGroupRepr::PREFIX)
|
if (name = TagGroupRepr.name_from_title(title))
|
||||||
exists = TagGroup.exists?(name: title.delete_prefix(TagGroupRepr::PREFIX))
|
exists = TagGroup.exists?(name:)
|
||||||
return head exists ? :no_content : :not_found
|
return head exists ? :no_content : :not_found
|
||||||
end
|
end
|
||||||
return head :no_content if tag_description_by_title(title)
|
|
||||||
|
return head :no_content if tag_description_by_title(locale, title)
|
||||||
|
|
||||||
head :not_found
|
head :not_found
|
||||||
end
|
end
|
||||||
@@ -80,15 +90,17 @@ class WikiPagesController < ApplicationController
|
|||||||
id = params[:id]
|
id = params[:id]
|
||||||
return render_bad_request('id は必須です.') if id.blank?
|
return render_bad_request('id は必須です.') if id.blank?
|
||||||
|
|
||||||
|
locale = resolve_locale!
|
||||||
|
|
||||||
from = params[:from].presence
|
from = params[:from].presence
|
||||||
to = params[:to].presence
|
to = params[:to].presence
|
||||||
|
|
||||||
description = TagDescription.find_by(id:)
|
description = TagDescription.find_by(id:, language_code: locale.language_code)
|
||||||
if description
|
if description
|
||||||
versions = description_versions(description)
|
versions = description_versions(description)
|
||||||
from_rev = from && versions.find(from)
|
from_rev = from && versions.find(from)
|
||||||
to_rev = to ? versions.find(to) : versions.find_by!(version_no: description.version_no)
|
to_rev = to ? versions.find(to) : versions.find_by!(version_no: description.version_no)
|
||||||
resource = WikiPageRepr.tag_description(description)
|
resource = WikiPageRepr.tag_description(locale, description)
|
||||||
else
|
else
|
||||||
tag_group = TagGroup.find_by(id:)
|
tag_group = TagGroup.find_by(id:)
|
||||||
if tag_group
|
if tag_group
|
||||||
@@ -96,8 +108,8 @@ class WikiPagesController < ApplicationController
|
|||||||
to_rev = to ? group_version(tag_group, to) : current_group_version(tag_group)
|
to_rev = to ? group_version(tag_group, to) : current_group_version(tag_group)
|
||||||
return head :not_found if (from && !from_rev) || !to_rev
|
return head :not_found if (from && !from_rev) || !to_rev
|
||||||
|
|
||||||
from_body = from_rev && render_group_version(from_rev)
|
from_body = from_rev && render_group_version(locale, from_rev)
|
||||||
to_body = render_group_version(to_rev)
|
to_body = render_group_version(locale, to_rev)
|
||||||
resource = { 'id' => tag_group.id,
|
resource = { 'id' => tag_group.id,
|
||||||
'title' => "#{ TagGroupRepr::PREFIX }#{ tag_group.name }",
|
'title' => "#{ TagGroupRepr::PREFIX }#{ tag_group.name }",
|
||||||
'deprecated_at' => nil }
|
'deprecated_at' => nil }
|
||||||
@@ -131,14 +143,15 @@ class WikiPagesController < ApplicationController
|
|||||||
return render_unprocessable_entity('タイトルは必須です.', field: :title) if title.blank?
|
return render_unprocessable_entity('タイトルは必須です.', field: :title) if title.blank?
|
||||||
return render_unprocessable_entity('本文は必須です.', field: :body) if body.blank?
|
return render_unprocessable_entity('本文は必須です.', field: :body) if body.blank?
|
||||||
|
|
||||||
if title.start_with?(TagGroupRepr::PREFIX)
|
locale = resolve_locale!
|
||||||
name = title.delete_prefix(TagGroupRepr::PREFIX)
|
|
||||||
parsed = TagGroupMarkdownParser.parse(body:, group: nil)
|
if (name = TagGroupRepr.name_from_title(title))
|
||||||
|
parsed = TagGroupMarkdownParser.parse(locale, body:, group: nil)
|
||||||
group = TagGroupOperation.create!(
|
group = TagGroupOperation.create!(
|
||||||
name:, **parsed.except(:compatibility_body), actor: current_user,
|
locale, name:, **parsed.except(:compatibility_body), actor: current_user,
|
||||||
require_compatibility: true)
|
require_compatibility: true)
|
||||||
version = current_group_version(group)
|
version = current_group_version(group)
|
||||||
return render_group_representation(TagGroupRepr.one(group), version,
|
return render_group_representation(TagGroupRepr.one(locale, group), version,
|
||||||
status: :created)
|
status: :created)
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -146,14 +159,15 @@ class WikiPagesController < ApplicationController
|
|||||||
if title.include?(':')
|
if title.include?(':')
|
||||||
return render_unprocessable_entity field: :title
|
return render_unprocessable_entity field: :title
|
||||||
else
|
else
|
||||||
tag_name = TagName.find_by(language_code: 'ja', name: title)
|
tag_name = TagName.find_by(language_code: locale.language_code, name: title)
|
||||||
return render_unprocessable_entity field: :title unless tag_name&.tag
|
return render_unprocessable_entity field: :title unless tag_name&.tag
|
||||||
|
|
||||||
TagDescriptionOperation.create!(
|
TagDescriptionOperation.create!(
|
||||||
|
locale,
|
||||||
tag: tag_name.tag, body:, created_by_user: current_user, message:)
|
tag: tag_name.tag, body:, created_by_user: current_user, message:)
|
||||||
end
|
end
|
||||||
|
|
||||||
render json: WikiPageRepr.tag_description(description), status: :created
|
render json: WikiPageRepr.tag_description(locale, description), status: :created
|
||||||
rescue ActiveRecord::RecordInvalid => e
|
rescue ActiveRecord::RecordInvalid => e
|
||||||
render_validation_error e.record
|
render_validation_error e.record
|
||||||
rescue ActiveRecord::RecordNotUnique
|
rescue ActiveRecord::RecordNotUnique
|
||||||
@@ -172,26 +186,28 @@ class WikiPagesController < ApplicationController
|
|||||||
return render_unprocessable_entity('タイトルは必須です.', field: :title) if title.blank?
|
return render_unprocessable_entity('タイトルは必須です.', field: :title) if title.blank?
|
||||||
return render_unprocessable_entity('本文は必須です.', field: :body) if body.blank?
|
return render_unprocessable_entity('本文は必須です.', field: :body) if body.blank?
|
||||||
|
|
||||||
|
locale = resolve_locale!
|
||||||
|
|
||||||
group = TagGroup.find_by(id: params[:id])
|
group = TagGroup.find_by(id: params[:id])
|
||||||
if title.start_with?(TagGroupRepr::PREFIX)
|
if (name = TagGroupRepr.name_from_title(title))
|
||||||
return head :not_found unless group
|
return head :not_found unless group
|
||||||
|
|
||||||
name = title.delete_prefix(TagGroupRepr::PREFIX)
|
parsed = TagGroupMarkdownParser.parse(locale, body:, group:)
|
||||||
parsed = TagGroupMarkdownParser.parse(body:, group:)
|
|
||||||
TagGroupOperation.update!(
|
TagGroupOperation.update!(
|
||||||
group:, name:, **parsed.except(:compatibility_body), actor: current_user,
|
locale, group:, name:, **parsed.except(:compatibility_body), actor: current_user,
|
||||||
require_compatibility: true)
|
require_compatibility: true)
|
||||||
return head :ok
|
return head :ok
|
||||||
end
|
end
|
||||||
|
|
||||||
return render_unprocessable_entity field: :title if title.include?(':')
|
return render_unprocessable_entity field: :title if title.include?(':')
|
||||||
description = TagDescription.find_by(id: params[:id])
|
description = TagDescription.find_by(id: params[:id], language_code: locale.language_code)
|
||||||
unless description
|
unless description
|
||||||
return render_unprocessable_entity field: :title if group
|
return render_unprocessable_entity field: :title if group
|
||||||
return head :not_found
|
return head :not_found
|
||||||
end
|
end
|
||||||
|
|
||||||
tag = description.tag
|
tag = description.tag
|
||||||
tag_name = tag.tag_name('ja')
|
tag_name = tag.tag_name(locale.language_code)
|
||||||
return render_unprocessable_entity field: :title unless tag_name
|
return render_unprocessable_entity field: :title unless tag_name
|
||||||
return render_unprocessable_entity field: :title if tag_name.name.include?(':')
|
return render_unprocessable_entity field: :title if tag_name.name.include?(':')
|
||||||
|
|
||||||
@@ -207,7 +223,7 @@ class WikiPagesController < ApplicationController
|
|||||||
tag_name.update!(name: title) if title != old_title
|
tag_name.update!(name: title) if title != old_title
|
||||||
|
|
||||||
message = params[:message].presence
|
message = params[:message].presence
|
||||||
TagDescriptionOperation.update!(tag:, body:, updated_by_user: current_user,
|
TagDescriptionOperation.update!(locale, tag:, body:, updated_by_user: current_user,
|
||||||
message:, base_revision_id:)
|
message:, base_revision_id:)
|
||||||
|
|
||||||
if title != old_title
|
if title != old_title
|
||||||
@@ -226,10 +242,12 @@ class WikiPagesController < ApplicationController
|
|||||||
end
|
end
|
||||||
|
|
||||||
def changes
|
def changes
|
||||||
|
locale = resolve_locale!
|
||||||
|
|
||||||
id = params[:id].presence
|
id = params[:id].presence
|
||||||
description = id && TagDescription.find_by(id:)
|
description = id && TagDescription.find_by(id:, language_code: locale.language_code)
|
||||||
if description
|
if description
|
||||||
return render json: description_changes(TagDescription.where(id: description.id))
|
return render json: description_changes(locale, TagDescription.where(id: description.id))
|
||||||
end
|
end
|
||||||
|
|
||||||
tag_group = id && TagGroup.find_by(id:)
|
tag_group = id && TagGroup.find_by(id:)
|
||||||
@@ -240,7 +258,8 @@ class WikiPagesController < ApplicationController
|
|||||||
json = []
|
json = []
|
||||||
unless id
|
unless id
|
||||||
json.concat(tag_group_changes(TagGroupVersion.all))
|
json.concat(tag_group_changes(TagGroupVersion.all))
|
||||||
json.concat(description_changes(TagDescription.where(language_code: 'ja')))
|
json.concat(description_changes(locale,
|
||||||
|
TagDescription.where(language_code: locale.language_code)))
|
||||||
json = json.each_with_index.sort_by do |row, index|
|
json = json.each_with_index.sort_by do |row, index|
|
||||||
[-row.fetch(:timestamp).to_f, index]
|
[-row.fetch(:timestamp).to_f, index]
|
||||||
end.map(&:first)
|
end.map(&:first)
|
||||||
@@ -250,7 +269,7 @@ class WikiPagesController < ApplicationController
|
|||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def render_tag_group group
|
def render_tag_group locale, group
|
||||||
version = if params[:version].present?
|
version = if params[:version].present?
|
||||||
group_version(group, params[:version])
|
group_version(group, params[:version])
|
||||||
else
|
else
|
||||||
@@ -258,16 +277,17 @@ class WikiPagesController < ApplicationController
|
|||||||
end
|
end
|
||||||
return head :not_found unless version
|
return head :not_found unless version
|
||||||
|
|
||||||
representation = if params[:version].present?
|
representation =
|
||||||
TagGroupRepr.historical(version)
|
if params[:version].present?
|
||||||
else
|
TagGroupRepr.historical(locale, version)
|
||||||
TagGroupRepr.one(group)
|
else
|
||||||
end
|
TagGroupRepr.one(locale, group)
|
||||||
|
end
|
||||||
render_group_representation(representation, version)
|
render_group_representation(representation, version)
|
||||||
end
|
end
|
||||||
|
|
||||||
def render_group_version version
|
def render_group_version locale, version
|
||||||
representation = TagGroupRepr.historical(version)
|
representation = TagGroupRepr.historical(locale, version)
|
||||||
TagGroupMarkdownRenderer.render(representation)
|
TagGroupMarkdownRenderer.render(representation)
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -336,7 +356,7 @@ class WikiPagesController < ApplicationController
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def render_wiki_page_by_tag_description description
|
def render_wiki_page_by_tag_description locale, description
|
||||||
versions = description_versions(description)
|
versions = description_versions(description)
|
||||||
historical = params[:version].present?
|
historical = params[:version].present?
|
||||||
rev = historical ? versions.find_by(id: params[:version]) :
|
rev = historical ? versions.find_by(id: params[:version]) :
|
||||||
@@ -347,7 +367,7 @@ class WikiPagesController < ApplicationController
|
|||||||
succ = versions.find_by(version_no: rev.version_no + 1)&.id
|
succ = versions.find_by(version_no: rev.version_no + 1)&.id
|
||||||
body = historical ? rev.body : description.body
|
body = historical ? rev.body : description.body
|
||||||
updated_at = historical ? rev.created_at : description.updated_at
|
updated_at = historical ? rev.created_at : description.updated_at
|
||||||
render json: WikiPageRepr.tag_description(description).merge(
|
render json: WikiPageRepr.tag_description(locale, description).merge(
|
||||||
body:, revision_id: rev.id, pred:, succ:, updated_at:)
|
body:, revision_id: rev.id, pred:, succ:, updated_at:)
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -356,13 +376,14 @@ class WikiPagesController < ApplicationController
|
|||||||
language_code: description.language_code)
|
language_code: description.language_code)
|
||||||
end
|
end
|
||||||
|
|
||||||
def tag_description_by_title title
|
def tag_description_by_title locale, title
|
||||||
TagDescription.joins(tag: :tag_names)
|
TagDescription.joins(tag: :tag_names)
|
||||||
.find_by(language_code: 'ja', tag_names: { language_code: 'ja', name: title })
|
.find_by(language_code: locale.language_code,
|
||||||
|
tag_names: { language_code: locale.language_code, name: title })
|
||||||
end
|
end
|
||||||
|
|
||||||
def description_changes descriptions
|
def description_changes locale, descriptions
|
||||||
versions = TagDescriptionVersion.where(language_code: 'ja',
|
versions = TagDescriptionVersion.where(language_code: locale.language_code,
|
||||||
tag_id: descriptions.select(:tag_id))
|
tag_id: descriptions.select(:tag_id))
|
||||||
.order(id: :desc).limit(200).to_a
|
.order(id: :desc).limit(200).to_a
|
||||||
return [] if versions.empty?
|
return [] if versions.empty?
|
||||||
@@ -371,7 +392,7 @@ class WikiPagesController < ApplicationController
|
|||||||
.includes(tag: :tag_names).index_by(&:tag_id)
|
.includes(tag: :tag_names).index_by(&:tag_id)
|
||||||
users = User.where(id: versions.map(&:created_by_user_id)).index_by(&:id)
|
users = User.where(id: versions.map(&:created_by_user_id)).index_by(&:id)
|
||||||
predecessors = TagDescriptionVersion.where(
|
predecessors = TagDescriptionVersion.where(
|
||||||
language_code: 'ja', tag_id: by_tag.keys,
|
language_code: locale.language_code, tag_id: by_tag.keys,
|
||||||
version_no: versions.map { |version| version.version_no - 1 })
|
version_no: versions.map { |version| version.version_no - 1 })
|
||||||
.pluck(:tag_id, :version_no, :id)
|
.pluck(:tag_id, :version_no, :id)
|
||||||
.to_h { |tag_id, version_no, id| [[tag_id, version_no], id] }
|
.to_h { |tag_id, version_no, id| [[tag_id, version_no], id] }
|
||||||
@@ -381,7 +402,7 @@ class WikiPagesController < ApplicationController
|
|||||||
{ revision_id: version.id,
|
{ revision_id: version.id,
|
||||||
pred: predecessors[[version.tag_id, version.version_no - 1]],
|
pred: predecessors[[version.tag_id, version.version_no - 1]],
|
||||||
succ: nil,
|
succ: nil,
|
||||||
wiki_page: { id: description.id, title: description.tag.name('ja'),
|
wiki_page: { id: description.id, title: description.tag.name(locale.language_code),
|
||||||
deprecated_at: description.tag.deprecated_at },
|
deprecated_at: description.tag.deprecated_at },
|
||||||
user: user && { id: user.id, name: user.name },
|
user: user && { id: user.id, name: user.name },
|
||||||
kind: 'content',
|
kind: 'content',
|
||||||
|
|||||||
@@ -3,7 +3,12 @@ module TagGroupRepr
|
|||||||
|
|
||||||
module_function
|
module_function
|
||||||
|
|
||||||
def many groups
|
def name_from_title title
|
||||||
|
prefix = [PREFIX, 'tag_group:'].find { title.downcase.start_with?(_1) }
|
||||||
|
title[prefix.length..] if prefix
|
||||||
|
end
|
||||||
|
|
||||||
|
def many locale, groups
|
||||||
ids = groups.map(&:id)
|
ids = groups.map(&:id)
|
||||||
return [] if ids.empty?
|
return [] if ids.empty?
|
||||||
|
|
||||||
@@ -14,14 +19,20 @@ module TagGroupRepr
|
|||||||
placements = TagGroupPlacement.where(tag_group_id: ids).order(:position)
|
placements = TagGroupPlacement.where(tag_group_id: ids).order(:position)
|
||||||
.group_by(&:tag_group_id)
|
.group_by(&:tag_group_id)
|
||||||
|
|
||||||
target_ids = tag_members.values.flatten.map(&:tag_id) +
|
target_ids =
|
||||||
group_members.values.flatten.map(&:child_tag_group_id) +
|
tag_members.values.flatten.map(&:tag_id) +
|
||||||
placements.values.flatten.filter_map(&:tag_id)
|
placements.values.flatten.filter_map(&:tag_id)
|
||||||
child_ids = group_members.values.flatten.map(&:child_tag_group_id) +
|
child_ids =
|
||||||
|
group_members.values.flatten.map(&:child_tag_group_id) +
|
||||||
placements.values.flatten.filter_map(&:child_tag_group_id)
|
placements.values.flatten.filter_map(&:child_tag_group_id)
|
||||||
tags = Tag.select(:id, :category).where(id: target_ids.uniq).index_by(&:id)
|
tags = Tag.select(:id, :category).where(id: target_ids.uniq).index_by(&:id)
|
||||||
names = TagName.where(tag_id: target_ids.uniq, language_code: 'ja', primary_flg: true)
|
names =
|
||||||
.pluck(:tag_id, :name).to_h
|
TagName
|
||||||
|
.where(tag_id: target_ids.uniq,
|
||||||
|
language_code: locale.language_code,
|
||||||
|
primary_flg: true)
|
||||||
|
.pluck(:tag_id, :name)
|
||||||
|
.to_h
|
||||||
child_groups = TagGroup.where(id: child_ids.uniq).index_by(&:id)
|
child_groups = TagGroup.where(id: child_ids.uniq).index_by(&:id)
|
||||||
|
|
||||||
groups.map do |group|
|
groups.map do |group|
|
||||||
@@ -32,8 +43,8 @@ module TagGroupRepr
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def one group
|
def one locale, group
|
||||||
many([group]).first
|
many(locale, [group]).first
|
||||||
end
|
end
|
||||||
|
|
||||||
def tag_group wiki_page
|
def tag_group wiki_page
|
||||||
@@ -48,7 +59,7 @@ module TagGroupRepr
|
|||||||
TagGroupVersion.find_by(tag_group_id: group.id, version_no: group.version_no)
|
TagGroupVersion.find_by(tag_group_id: group.id, version_no: group.version_no)
|
||||||
end
|
end
|
||||||
|
|
||||||
def historical version
|
def historical locale, version
|
||||||
members = Array(version.members)
|
members = Array(version.members)
|
||||||
placements = Array(version.placements)
|
placements = Array(version.placements)
|
||||||
tag_references = members.filter_map { |member| member['tag_id'] } +
|
tag_references = members.filter_map { |member| member['tag_id'] } +
|
||||||
@@ -68,10 +79,10 @@ module TagGroupRepr
|
|||||||
[member.fetch('tag_group_id'), member.fetch('version_no')]
|
[member.fetch('tag_group_id'), member.fetch('version_no')]
|
||||||
end.to_h
|
end.to_h
|
||||||
historical_members = members.map do |member|
|
historical_members = members.map do |member|
|
||||||
historical_member(member, tag_versions, group_versions)
|
historical_member(locale, member, tag_versions, group_versions)
|
||||||
end
|
end
|
||||||
historical_placements = placements.map do |node|
|
historical_placements = placements.map do |node|
|
||||||
historical_placement(node, tag_versions, group_versions,
|
historical_placement(locale, node, tag_versions, group_versions,
|
||||||
tag_version_numbers, group_version_numbers)
|
tag_version_numbers, group_version_numbers)
|
||||||
end
|
end
|
||||||
{ 'id' => version.tag_group_id,
|
{ 'id' => version.tag_group_id,
|
||||||
@@ -89,7 +100,7 @@ module TagGroupRepr
|
|||||||
def group_json group, tag_members, group_members, rows, tags, names, child_groups
|
def group_json group, tag_members, group_members, rows, tags, names, child_groups
|
||||||
tree = placement_tree(rows, tags, names, child_groups)
|
tree = placement_tree(rows, tags, names, child_groups)
|
||||||
members = tag_members.sort_by(&:tag_id).map do |member|
|
members = tag_members.sort_by(&:tag_id).map do |member|
|
||||||
{ 'tag' => tag_json(tags.fetch(member.tag_id), names.fetch(member.tag_id)) }
|
{ 'tag' => tag_json(tags.fetch(member.tag_id), names[member.tag_id]) }
|
||||||
end
|
end
|
||||||
members.concat(group_members.sort_by(&:child_tag_group_id).map do |member|
|
members.concat(group_members.sort_by(&:child_tag_group_id).map do |member|
|
||||||
{ 'tag_group' => group_json_reference(child_groups.fetch(member.child_tag_group_id)) }
|
{ 'tag_group' => group_json_reference(child_groups.fetch(member.child_tag_group_id)) }
|
||||||
@@ -115,7 +126,7 @@ module TagGroupRepr
|
|||||||
build = lambda do |parent|
|
build = lambda do |parent|
|
||||||
by_parent.fetch(parent, []).sort_by(&:position).map do |row|
|
by_parent.fetch(parent, []).sort_by(&:position).map do |row|
|
||||||
node = if row.tag_id
|
node = if row.tag_id
|
||||||
{ 'tag' => tag_json(tags.fetch(row.tag_id), names.fetch(row.tag_id)) }
|
{ 'tag' => tag_json(tags.fetch(row.tag_id), names[row.tag_id]) }
|
||||||
elsif row.child_tag_group_id
|
elsif row.child_tag_group_id
|
||||||
{ 'tag_group' => group_json_reference(child_groups.fetch(row.child_tag_group_id)) }
|
{ 'tag_group' => group_json_reference(child_groups.fetch(row.child_tag_group_id)) }
|
||||||
else
|
else
|
||||||
@@ -153,11 +164,11 @@ module TagGroupRepr
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def historical_member member, tag_versions, group_versions
|
def historical_member locale, member, tag_versions, group_versions
|
||||||
if member['tag_id']
|
if member['tag_id']
|
||||||
id = member.fetch('tag_id')
|
id = member.fetch('tag_id')
|
||||||
version = tag_versions.fetch([id, member.fetch('version_no')])
|
version = tag_versions.fetch([id, member.fetch('version_no')])
|
||||||
{ 'tag' => { 'id' => id, 'name' => japanese_version_name(version),
|
{ 'tag' => { 'id' => id, 'name' => version_name(locale, version),
|
||||||
'category' => version.category } }
|
'category' => version.category } }
|
||||||
else
|
else
|
||||||
id = member.fetch('tag_group_id')
|
id = member.fetch('tag_group_id')
|
||||||
@@ -166,13 +177,13 @@ module TagGroupRepr
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def historical_placement(node, tag_versions, group_versions,
|
def historical_placement locale, node, tag_versions, group_versions,
|
||||||
tag_version_numbers, group_version_numbers)
|
tag_version_numbers, group_version_numbers
|
||||||
result = if node['tag_id']
|
result = if node['tag_id']
|
||||||
id = node.fetch('tag_id')
|
id = node.fetch('tag_id')
|
||||||
version_no = tag_version_numbers.fetch(id)
|
version_no = tag_version_numbers.fetch(id)
|
||||||
version = tag_versions.fetch([id, version_no])
|
version = tag_versions.fetch([id, version_no])
|
||||||
{ 'tag' => { 'id' => id, 'name' => japanese_version_name(version),
|
{ 'tag' => { 'id' => id, 'name' => version_name(locale, version),
|
||||||
'category' => version.category } }
|
'category' => version.category } }
|
||||||
elsif node['tag_group_id']
|
elsif node['tag_group_id']
|
||||||
id = node.fetch('tag_group_id')
|
id = node.fetch('tag_group_id')
|
||||||
@@ -183,12 +194,12 @@ module TagGroupRepr
|
|||||||
{ 'section_name' => node.fetch('section_name'), 'description' => node['description'] }
|
{ 'section_name' => node.fetch('section_name'), 'description' => node['description'] }
|
||||||
end
|
end
|
||||||
result.merge('children' => Array(node['children']).map do |child|
|
result.merge('children' => Array(node['children']).map do |child|
|
||||||
historical_placement(child, tag_versions, group_versions,
|
historical_placement(locale, child, tag_versions, group_versions,
|
||||||
tag_version_numbers, group_version_numbers)
|
tag_version_numbers, group_version_numbers)
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
def japanese_version_name version
|
def version_name locale, version
|
||||||
version.names.fetch('ja').fetch('name')
|
version.names[locale.language_code]&.fetch('name')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -4,11 +4,12 @@
|
|||||||
module WikiPageRepr
|
module WikiPageRepr
|
||||||
module_function
|
module_function
|
||||||
|
|
||||||
def tag_description description
|
def tag_description locale, description
|
||||||
tag = description.tag
|
tag = description.tag
|
||||||
|
|
||||||
{ 'id' => description.id,
|
{ 'id' => description.id,
|
||||||
'resource_type' => 'tag_description',
|
'resource_type' => 'tag_description',
|
||||||
'tag_name_id' => tag.tag_name('ja')&.id,
|
'tag_name_id' => tag.tag_name(locale.language_code)&.id,
|
||||||
'body' => description.body,
|
'body' => description.body,
|
||||||
'created_user_id' => description.created_by_user_id,
|
'created_user_id' => description.created_by_user_id,
|
||||||
'updated_user_id' => description.updated_by_user_id,
|
'updated_user_id' => description.updated_by_user_id,
|
||||||
@@ -16,7 +17,7 @@ module WikiPageRepr
|
|||||||
'updated_at' => description.updated_at,
|
'updated_at' => description.updated_at,
|
||||||
'discarded_at' => nil,
|
'discarded_at' => nil,
|
||||||
'version_no' => description.version_no,
|
'version_no' => description.version_no,
|
||||||
'title' => tag.name('ja'),
|
'title' => tag.name(locale.language_code),
|
||||||
'deprecated_at' => tag.deprecated_at }
|
'deprecated_at' => tag.deprecated_at }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -1,32 +1,30 @@
|
|||||||
class TagDescriptionOperation
|
class TagDescriptionOperation
|
||||||
LANGUAGE_CODE = 'ja'
|
|
||||||
|
|
||||||
class Conflict < StandardError
|
class Conflict < StandardError
|
||||||
;
|
;
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.create!(tag:, body:, created_by_user:, message: nil)
|
def self.create! locale, tag:, body:, created_by_user:, message: nil
|
||||||
ApplicationRecord.transaction do
|
ApplicationRecord.transaction do
|
||||||
tag.lock!
|
tag.lock!
|
||||||
raise ActiveRecord::RecordNotUnique if TagDescription.exists?(
|
raise ActiveRecord::RecordNotUnique if TagDescription.exists?(
|
||||||
tag_id: tag.id, language_code: LANGUAGE_CODE)
|
tag_id: tag.id, language_code: locale.language_code)
|
||||||
|
|
||||||
description = TagDescription.new(tag:, language_code: LANGUAGE_CODE)
|
description = TagDescription.new(tag:, language_code: locale.language_code)
|
||||||
body = normalise_body!(description, body)
|
body = normalise_body!(description, body)
|
||||||
record_version!(description:, body:, user: created_by_user)
|
record_version!(description:, body:, user: created_by_user)
|
||||||
|
|
||||||
description
|
description
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.update!(tag:, body:, updated_by_user:, message: nil,
|
def self.update! locale, tag:, body:, updated_by_user:, message: nil, base_revision_id: nil
|
||||||
base_revision_id: nil)
|
|
||||||
ApplicationRecord.transaction do
|
ApplicationRecord.transaction do
|
||||||
tag.lock!
|
tag.lock!
|
||||||
description = TagDescription.lock.find_by!(
|
description = TagDescription.lock.find_by!(
|
||||||
tag_id: tag.id, language_code: LANGUAGE_CODE)
|
tag_id: tag.id, language_code: locale.language_code)
|
||||||
body = normalise_body!(description, body)
|
body = normalise_body!(description, body)
|
||||||
latest = TagDescriptionVersion.find_by(
|
latest = TagDescriptionVersion.find_by(
|
||||||
tag_id: tag.id, language_code: LANGUAGE_CODE,
|
tag_id: tag.id, language_code: locale.language_code,
|
||||||
version_no: description.version_no)
|
version_no: description.version_no)
|
||||||
if base_revision_id.present? && latest&.id != base_revision_id.to_i
|
if base_revision_id.present? && latest&.id != base_revision_id.to_i
|
||||||
raise Conflict, '競合が発生してゐます.'
|
raise Conflict, '競合が発生してゐます.'
|
||||||
|
|||||||
@@ -7,8 +7,8 @@ class TagGroupMarkdownParser
|
|||||||
;
|
;
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.parse(body:, group: nil)
|
def self.parse(locale, body:, group: nil)
|
||||||
new(body:, group:).parse
|
new(body:, group:).parse(locale)
|
||||||
end
|
end
|
||||||
|
|
||||||
def initialize(body:, group:)
|
def initialize(body:, group:)
|
||||||
@@ -16,7 +16,7 @@ class TagGroupMarkdownParser
|
|||||||
@group = group
|
@group = group
|
||||||
end
|
end
|
||||||
|
|
||||||
def parse
|
def parse locale
|
||||||
parse_body = @body.gsub(/([^\n])\n([\x23]{1,6}[ \t]+\S)/, "\\1\n\n\\2")
|
parse_body = @body.gsub(/([^\n])\n([\x23]{1,6}[ \t]+\S)/, "\\1\n\n\\2")
|
||||||
root = Kramdown::Document.new(parse_body, input: 'GFM', auto_ids: false).root
|
root = Kramdown::Document.new(parse_body, input: 'GFM', auto_ids: false).root
|
||||||
placements = []
|
placements = []
|
||||||
@@ -51,7 +51,7 @@ class TagGroupMarkdownParser
|
|||||||
when :ul
|
when :ul
|
||||||
invalid!('未対応のリスト項目があります.') if node.attr.any?
|
invalid!('未対応のリスト項目があります.') if node.attr.any?
|
||||||
target = headings.any? ? headings.last.fetch(:node).fetch('children') : placements
|
target = headings.any? ? headings.last.fetch(:node).fetch('children') : placements
|
||||||
target.concat(node.children.map { parse_list_item(_1) })
|
target.concat(node.children.map { parse_list_item(locale, _1) })
|
||||||
else
|
else
|
||||||
invalid!("未対応の Markdown 構文 #{ node.type.inspect } です.")
|
invalid!("未対応の Markdown 構文 #{ node.type.inspect } です.")
|
||||||
end
|
end
|
||||||
@@ -66,7 +66,7 @@ class TagGroupMarkdownParser
|
|||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def parse_list_item(item)
|
def parse_list_item locale, item
|
||||||
invalid!('リスト項目ではありません.') unless item.type == :li
|
invalid!('リスト項目ではありません.') unless item.type == :li
|
||||||
invalid!('未対応のリスト項目があります.') if item.attr.any?
|
invalid!('未対応のリスト項目があります.') if item.attr.any?
|
||||||
|
|
||||||
@@ -81,29 +81,30 @@ class TagGroupMarkdownParser
|
|||||||
label = own.map { inline_text(_1) }.join(' ').strip
|
label = own.map { inline_text(_1) }.join(' ').strip
|
||||||
invalid!('空のリスト項目は使用できません.') if label.blank?
|
invalid!('空のリスト項目は使用できません.') if label.blank?
|
||||||
|
|
||||||
node = if label.start_with?(PREFIX)
|
node =
|
||||||
group_name = label.delete_prefix(PREFIX).strip
|
if (group_name = TagGroupRepr.name_from_title(label))
|
||||||
child_group = TagGroup.find_by(name: group_name)
|
group_name = group_name.strip
|
||||||
invalid!("Tag Group #{ group_name.inspect } を解決できません.") unless child_group
|
child_group = TagGroup.find_by(name: group_name)
|
||||||
invalid!('自分自身を含めることはできません.') if child_group.id == @group&.id
|
invalid!("Tag Group #{ group_name.inspect } を解決できません.") unless child_group
|
||||||
{ 'tag_group_id' => child_group.id }
|
invalid!('自分自身を含めることはできません.') if child_group.id == @group&.id
|
||||||
elsif label.end_with?(':', ':')
|
{ 'tag_group_id' => child_group.id }
|
||||||
section_name = label.sub(/[::]\z/, '').strip
|
elsif label.end_with?(':', ':')
|
||||||
invalid!('Section 名は必須です.') if section_name.blank?
|
section_name = label.sub(/[::]\z/, '').strip
|
||||||
{ 'section_name' => section_name, 'description' => nil }
|
invalid!('Section 名は必須です.') if section_name.blank?
|
||||||
else
|
{ 'section_name' => section_name, 'description' => nil }
|
||||||
{ 'tag_id' => resolve_tag(label) }
|
else
|
||||||
end
|
{ 'tag_id' => resolve_tag(locale, label) }
|
||||||
|
end
|
||||||
|
|
||||||
node['children'] = nested.flat_map do |list|
|
node['children'] = nested.flat_map do |list|
|
||||||
invalid!('未対応の入れ子リストです.') unless list.type == :ul
|
invalid!('未対応の入れ子リストです.') unless list.type == :ul
|
||||||
list.children.map { parse_list_item(_1) }
|
list.children.map { parse_list_item(locale, _1) }
|
||||||
end
|
end
|
||||||
node
|
node
|
||||||
end
|
end
|
||||||
|
|
||||||
def resolve_tag(name)
|
def resolve_tag locale, name
|
||||||
names = TagName.where(language_code: 'ja', name:).to_a
|
names = TagName.where(language_code: locale.language_code, name:).to_a
|
||||||
tag_ids = names.filter_map(&:tag_id).uniq
|
tag_ids = names.filter_map(&:tag_id).uniq
|
||||||
invalid!("Tag #{ name.inspect } を解決できません.") if tag_ids.empty?
|
invalid!("Tag #{ name.inspect } を解決できません.") if tag_ids.empty?
|
||||||
invalid!("Tag 名 #{ name.inspect } が曖昧です.") if tag_ids.many?
|
invalid!("Tag 名 #{ name.inspect } が曖昧です.") if tag_ids.many?
|
||||||
|
|||||||
@@ -1,29 +1,29 @@
|
|||||||
class TagGroupOperation
|
class TagGroupOperation
|
||||||
MAX_PLACEMENT_DEPTH = 5
|
MAX_PLACEMENT_DEPTH = 5
|
||||||
|
|
||||||
def self.create!(name:, description:, members:, placements:, actor:,
|
def self.create!(locale, name:, description:, members:, placements:, actor:,
|
||||||
require_compatibility: false)
|
require_compatibility: false)
|
||||||
ApplicationRecord.transaction do
|
ApplicationRecord.transaction do
|
||||||
group = TagGroup.new(version_no: 1, created_by_user: actor,
|
group = TagGroup.new(version_no: 1, created_by_user: actor,
|
||||||
updated_by_user: actor)
|
updated_by_user: actor)
|
||||||
attributes = prepare!(group:, name:, description:, members:, placements:)
|
attributes = prepare!(locale:, group:, name:, description:, members:, placements:)
|
||||||
group.assign_attributes(name: attributes.fetch(:name),
|
group.assign_attributes(name: attributes.fetch(:name),
|
||||||
description: attributes.fetch(:description))
|
description: attributes.fetch(:description))
|
||||||
group.save!
|
group.save!
|
||||||
persist_structure!(group:, attributes:, actor:)
|
persist_structure!(group:, attributes:, actor:)
|
||||||
validate_compatibility!(group) if require_compatibility
|
validate_compatibility!(locale, group) if require_compatibility
|
||||||
persist_version!(group:, attributes:, actor:, event_type: 'create')
|
persist_version!(group:, attributes:, actor:, event_type: 'create')
|
||||||
group
|
group
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.update!(group:, name:, description:, members:, placements:, actor:,
|
def self.update!(locale, group:, name:, description:, members:, placements:, actor:,
|
||||||
require_compatibility: false)
|
require_compatibility: false)
|
||||||
ApplicationRecord.transaction do
|
ApplicationRecord.transaction do
|
||||||
group.lock!
|
group.lock!
|
||||||
attributes = prepare!(group:, name:, description:, members:, placements:)
|
attributes = prepare!(locale:, group:, name:, description:, members:, placements:)
|
||||||
if unchanged?(group, attributes)
|
if unchanged?(group, attributes)
|
||||||
validate_compatibility!(group) if require_compatibility
|
validate_compatibility!(locale, group) if require_compatibility
|
||||||
next group
|
next group
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -32,20 +32,20 @@ class TagGroupOperation
|
|||||||
version_no: group.version_no + 1,
|
version_no: group.version_no + 1,
|
||||||
updated_by_user: actor)
|
updated_by_user: actor)
|
||||||
persist_structure!(group:, attributes:, actor:)
|
persist_structure!(group:, attributes:, actor:)
|
||||||
validate_compatibility!(group) if require_compatibility
|
validate_compatibility!(locale, group) if require_compatibility
|
||||||
persist_version!(group:, attributes:, actor:, event_type: 'update')
|
persist_version!(group:, attributes:, actor:, event_type: 'update')
|
||||||
group
|
group
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.validate_compatibility! group
|
def self.validate_compatibility! locale, group
|
||||||
TagGroupMarkdownRenderer.render(TagGroupRepr.one(group))
|
TagGroupMarkdownRenderer.render(TagGroupRepr.one(locale, group))
|
||||||
rescue TagGroupMarkdownRenderer::UnsupportedStructure => error
|
rescue TagGroupMarkdownRenderer::UnsupportedStructure => error
|
||||||
invalid!(group, :base, error.message)
|
invalid!(group, :base, error.message)
|
||||||
end
|
end
|
||||||
private_class_method :validate_compatibility!
|
private_class_method :validate_compatibility!
|
||||||
|
|
||||||
def self.prepare!(group:, name:, description:, members:, placements:)
|
def self.prepare!(locale:, group:, name:, description:, members:, placements:)
|
||||||
record = group
|
record = group
|
||||||
normalized_name = name.to_s.strip
|
normalized_name = name.to_s.strip
|
||||||
invalid!(record, :name, 'グループ名は必須です.') if normalized_name.blank?
|
invalid!(record, :name, 'グループ名は必須です.') if normalized_name.blank?
|
||||||
@@ -63,7 +63,7 @@ class TagGroupOperation
|
|||||||
|
|
||||||
member_rows = normalize_members(record, members)
|
member_rows = normalize_members(record, members)
|
||||||
placement_tree = normalize_placements(record, placements)
|
placement_tree = normalize_placements(record, placements)
|
||||||
validate_references!(record, member_rows, placement_tree)
|
validate_references!(locale, record, member_rows, placement_tree)
|
||||||
validate_containment!(record, member_rows)
|
validate_containment!(record, member_rows)
|
||||||
{ name: normalized_name, description:, members: member_rows,
|
{ name: normalized_name, description:, members: member_rows,
|
||||||
placements: placement_tree }
|
placements: placement_tree }
|
||||||
@@ -187,7 +187,7 @@ class TagGroupOperation
|
|||||||
end
|
end
|
||||||
private_class_method :normalize_placement_nodes
|
private_class_method :normalize_placement_nodes
|
||||||
|
|
||||||
def self.validate_references!(record, members, placements)
|
def self.validate_references!(locale, record, members, placements)
|
||||||
membership = members.to_set
|
membership = members.to_set
|
||||||
placed = placement_references(placements).uniq
|
placed = placement_references(placements).uniq
|
||||||
missing = placed - membership.to_a
|
missing = placed - membership.to_a
|
||||||
@@ -206,13 +206,14 @@ class TagGroupOperation
|
|||||||
tag_versions = TagVersion.where(tag_id: tag_ids).pluck(:tag_id, :version_no).to_set
|
tag_versions = TagVersion.where(tag_id: tag_ids).pluck(:tag_id, :version_no).to_set
|
||||||
group_versions = TagGroupVersion.where(tag_group_id: group_ids)
|
group_versions = TagGroupVersion.where(tag_group_id: group_ids)
|
||||||
.pluck(:tag_group_id, :version_no).to_set
|
.pluck(:tag_group_id, :version_no).to_set
|
||||||
tag_names = TagName.where(tag_id: tag_ids, language_code: 'ja', primary_flg: true)
|
tag_names = TagName.where(
|
||||||
|
tag_id: tag_ids, language_code: locale.language_code, primary_flg: true)
|
||||||
.pluck(:tag_id).uniq
|
.pluck(:tag_id).uniq
|
||||||
|
|
||||||
members.each do |member|
|
members.each do |member|
|
||||||
if member.key?('tag_id')
|
if member.key?('tag_id')
|
||||||
id = member.fetch('tag_id')
|
id = member.fetch('tag_id')
|
||||||
invalid!(record, :members, "Tag ##{ id } に日本語の正規名がありません.") unless
|
invalid!(record, :members, :invalid) unless
|
||||||
tag_names.include?(id)
|
tag_names.include?(id)
|
||||||
version_no = tags.fetch(id).version_no
|
version_no = tags.fetch(id).version_no
|
||||||
unless tag_versions.include?([id, version_no])
|
unless tag_versions.include?([id, version_no])
|
||||||
|
|||||||
新しいイシューから参照
ユーザーをブロックする