このコミットが含まれているのは:
2026-09-30 00:30:05 +09:00
コミット 1e398bfb97
13個のファイルの変更、385行の追加、346行の削除
+2
ファイルの表示
@@ -1,3 +1,5 @@
class Language < ApplicationRecord class Language < ApplicationRecord
has_many :locales, foreign_key: :language_code, primary_key: :code has_many :locales, foreign_key: :language_code, primary_key: :code
enum :code, ja: 'ja', en: 'en', fr: 'fr'
end end
+13 -10
ファイルの表示
@@ -4,21 +4,24 @@ class Locale < ApplicationRecord
belongs_to :language, foreign_key: :language_code, primary_key: :code belongs_to :language, foreign_key: :language_code, primary_key: :code
belongs_to :script, foreign_key: :script_code, primary_key: :code belongs_to :script, foreign_key: :script_code, primary_key: :code
enum :code, ja: 'ja', en: 'en', fr: 'fr'
def self.nipponese = Locale.find('ja') def self.nipponese = Locale.find('ja')
private private
def generate_tag_names! def generate_tag_names!
tag_ids = TagName.where(language_code:, primary_flg: true).pluck(:tag_id) ApplicationRecord.transaction do
Tag.where.not(id: tag_ids).find_each do tag_ids = TagName.where(language_code:, primary_flg: true).pluck(:tag_id)
TagName.create!(tag_id: _1.id, Tag.where.not(id: tag_ids).find_each do
language_code:, TagName.create!(tag_id: _1.id,
name: TagName.generate_name(self, _1, _1.name('ja')), language_code:,
script_code:, name: TagName.generate_name(self, _1, _1.tag_name('ja')),
primary_flg: true, script_code:,
# TODO: 公証実装したら書く. primary_flg: true,
# auto_generated: true, auto_generated: true,
canonical_id: nil) canonical_id: nil)
end
end end
end end
end end
+3 -1
ファイルの表示
@@ -1,3 +1,5 @@
class Script < ApplicationRecord class Script < ApplicationRecord
; has_many :locales, foreign_key: :language_code, primary_key: :code
enum :code, Jpan: 'Jpan', Latn: 'Latn'
end end
+256 -229
ファイルの表示
@@ -102,209 +102,6 @@ class Tag < ApplicationRecord
def has_deerjikists = deerjikists.loaded? ? deerjikists.any? : deerjikists.exists? def has_deerjikists = deerjikists.loaded? ? deerjikists.any? : deerjikists.exists?
def self.tagme = find_or_create_by_tag_name!(Locale.nipponese, 'タグ希望', category: :meta)
def self.bot = find_or_create_by_tag_name!(Locale.nipponese, 'bot操作', category: :meta)
def self.no_deerjikist =
find_or_create_by_tag_name!(Locale.nipponese, 'ニジラー情報不詳', category: :meta)
def self.video = find_or_create_by_tag_name!(Locale.nipponese, '動画', category: :meta)
def self.niconico = find_or_create_by_tag_name!(Locale.nipponese, 'ニコニコ', category: :meta)
def self.youtube = find_or_create_by_tag_name!(Locale.nipponese, 'YouTube', category: :meta)
def self.normalise_tags! locale, tag_names,
with_tagme: true,
with_no_deerjikist: true,
deny_deprecated: false,
with_sections: false
if tag_names.any? { |n| n.downcase.start_with?('nico:') }
raise NicoTagNormalisationError
end
sections = { }
tags = tag_names.map do |name|
raw_name = name
pf, cat = CATEGORY_PREFIXES.find { |p, _| name.downcase.start_with?(p) } || ['', nil]
name = name.sub(/\A#{ pf }/i, '')
sections_by_tag = []
while (match = name.match(/\A(\S*?)\[([^\[\]\s]*)-([^\[\]\s]*)\](\S*)\z/))
name = "#{ match[1] }#{ match[4] }"
next if match[2].empty? && match[3].empty?
sections_by_tag << normalise_section_range!(
begin_raw: match[2],
end_raw: match[3],
tag_name: name)
end
if name.include?('[') || name.include?(']')
raise SectionLiteralParseError.new(raw_name, raw_name)
end
name = TagName.canonicalise(locale, name).first
find_or_create_by_tag_name!(locale, name, category: (cat || :general)).tap do |tag|
if deny_deprecated && tag.deprecated?
raise DeprecatedTagNormalisationError, [tag.name(locale.language_code)]
end
tag.update!(category: cat) if cat && tag.category != cat
next if sections_by_tag.empty?
sections[tag.id] ||= []
sections[tag.id].concat(sections_by_tag)
sections[tag.id] = merge_section_ranges(sections[tag.id])
sections.delete(tag.id) if sections[tag.id] == [[0, nil]]
end
end
tags << Tag.tagme if with_tagme && tags.size < 10 && tags.none?(Tag.tagme)
tags << Tag.no_deerjikist if with_no_deerjikist && tags.all? { |t| !(t.deerjikist?) }
tags.uniq!(&:id)
if with_sections
{ tags:, sections: }
else
tags
end
end
def self.expand_parent_tags tags
return [] if tags.blank?
seen = Set.new
result = []
stack = tags.compact.dup
until stack.empty?
tag = stack.pop
next unless tag
tag.parents.each do |parent|
next if seen.include?(parent.id)
seen << parent.id
result << parent
stack << parent
end
end
(result + tags).uniq { |t| t.id }
end
def self.normalise_section_range! begin_raw:, end_raw:, tag_name:
begin_ms = begin_raw.empty? ? 0 : time_to_ms!(begin_raw, tag_name:)
end_ms = end_raw.empty? ? nil : time_to_ms!(end_raw, tag_name:)
if end_ms
begin_ms, end_ms = end_ms, begin_ms if begin_ms > end_ms
end_ms = begin_ms + 1 if begin_ms == end_ms
end
[begin_ms, end_ms]
end
def self.merge_section_ranges ranges
sorted_ranges = ranges.sort_by { |begin_ms, end_ms| [begin_ms, end_ms || Float::INFINITY] }
merged = []
sorted_ranges.each do |begin_ms, end_ms|
if merged.empty?
merged << [begin_ms, end_ms]
next
end
last_begin_ms, last_end_ms = merged[-1]
if last_end_ms.nil? || begin_ms <= last_end_ms
merged[-1] = [last_begin_ms, merge_section_end(last_end_ms, end_ms)]
else
merged << [begin_ms, end_ms]
end
end
merged
end
def self.merge_section_end left_end_ms, right_end_ms
return nil if left_end_ms.nil? || right_end_ms.nil?
[left_end_ms, right_end_ms].max
end
def self.find_or_create_by_tag_name! locale, name, category:
language_code = locale.language_code
name = name.to_s.strip
tn = TagName.find_or_create_by!(language_code:, name:) do
_1.script_code = locale.script_code
_1.primary_flg = true
end
tag = tn.tag
return tag if tag
tag = Tag.create!(tag_name_id: tn.id, category:)
tn.update!(tag:)
tag.association(:tag_names).reset
tag
rescue ActiveRecord::RecordNotUnique
retry
end
def self.merge_tags! target_tag, source_tags, created_by_user: nil
target_tag => Tag
affected_post_ids = Set.new
Tag.transaction do
TagVersioning.ensure_snapshot!(target_tag, created_by_user:)
Array(source_tags).compact.uniq.each do |source_tag|
source_tag => Tag
next if source_tag == target_tag
TagVersioning.ensure_snapshot!(source_tag, created_by_user:)
source_tag.post_tags.find_each do |source_pt|
post_id = source_pt.post_id
affected_post_ids << post_id
source_pt.destroy!
unless PostTag.exists?(post_id:, tag: target_tag)
PostTag.create!(post_id:, tag: target_tag)
end
end
source_tag_name = source_tag.tag_name('ja')
if source_tag_name.wiki_page.present?
raise ActiveRecord::RecordInvalid.new(source_tag_name)
end
TagVersioning.record!(source_tag, event_type: :discard, created_by_user:)
source_tag.tag_names.update_all(tag_id: target_tag.id, primary_flg: false,
updated_at: Time.current)
source_tag.destroy!
source_tag_name.update_columns(canonical_id: target_tag.tag_name_id,
updated_at: Time.current)
TagVersioning.record!(target_tag, event_type: :update, created_by_user:)
end
Post.where(id: affected_post_ids.to_a).find_each do |post|
PostVersionRecorder.ensure_snapshot!(post, created_by_user:)
PostVersionRecorder.record!(post:, event_type: :update, created_by_user:)
end
# 投稿件数を再集計
target_tag.update_columns(post_count: PostTag.where(tag: target_tag).count)
end
target_tag.reload
end
def snapshot_aliases(language_code) def snapshot_aliases(language_code)
tag_names.where(language_code:, primary_flg: false).order(:name).pluck(:name) tag_names.where(language_code:, primary_flg: false).order(:name).pluck(:name)
end end
@@ -319,6 +116,262 @@ class Tag < ApplicationRecord
.pluck('tag_names.name') .pluck('tag_names.name')
end end
class << self
def tagme = find_or_create_by_tag_name!(Locale.nipponese, 'タグ希望', category: :meta)
def bot = find_or_create_by_tag_name!(Locale.nipponese, 'bot操作', category: :meta)
def no_deerjikist =
find_or_create_by_tag_name!(Locale.nipponese, 'ニジラー情報不詳', category: :meta)
def video = find_or_create_by_tag_name!(Locale.nipponese, '動画', category: :meta)
def niconico = find_or_create_by_tag_name!(Locale.nipponese, 'ニコニコ', category: :meta)
def youtube = find_or_create_by_tag_name!(Locale.nipponese, 'YouTube', category: :meta)
def normalise_tags! locale, tag_names,
with_tagme: true,
with_no_deerjikist: true,
deny_deprecated: false,
with_sections: false
if tag_names.any? { |n| n.downcase.start_with?('nico:') }
raise NicoTagNormalisationError
end
sections = { }
tags = tag_names.map do |name|
raw_name = name
pf, cat = CATEGORY_PREFIXES.find { |p, _| name.downcase.start_with?(p) } || ['', nil]
name = name.sub(/\A#{ pf }/i, '')
sections_by_tag = []
while (match = name.match(/\A(\S*?)\[([^\[\]\s]*)-([^\[\]\s]*)\](\S*)\z/))
name = "#{ match[1] }#{ match[4] }"
next if match[2].empty? && match[3].empty?
sections_by_tag << normalise_section_range!(
begin_raw: match[2],
end_raw: match[3],
tag_name: name)
end
if name.include?('[') || name.include?(']')
raise SectionLiteralParseError.new(raw_name, raw_name)
end
name = TagName.canonicalise(locale, name).first
find_or_create_by_tag_name!(locale, name, category: (cat || :general)).tap do |tag|
if deny_deprecated && tag.deprecated?
raise DeprecatedTagNormalisationError, [tag.name(locale.language_code)]
end
tag.update!(category: cat) if cat && tag.category != cat
next if sections_by_tag.empty?
sections[tag.id] ||= []
sections[tag.id].concat(sections_by_tag)
sections[tag.id] = merge_section_ranges(sections[tag.id])
sections.delete(tag.id) if sections[tag.id] == [[0, nil]]
end
end
tags << Tag.tagme if with_tagme && tags.size < 10 && tags.none?(Tag.tagme)
tags << Tag.no_deerjikist if with_no_deerjikist && tags.all? { |t| !(t.deerjikist?) }
tags.uniq!(&:id)
if with_sections
{ tags:, sections: }
else
tags
end
end
def expand_parent_tags tags
return [] if tags.blank?
seen = Set.new
result = []
stack = tags.compact.dup
until stack.empty?
tag = stack.pop
next unless tag
tag.parents.each do |parent|
next if seen.include?(parent.id)
seen << parent.id
result << parent
stack << parent
end
end
(result + tags).uniq { |t| t.id }
end
def normalise_section_range! begin_raw:, end_raw:, tag_name:
begin_ms = begin_raw.empty? ? 0 : time_to_ms!(begin_raw, tag_name:)
end_ms = end_raw.empty? ? nil : time_to_ms!(end_raw, tag_name:)
if end_ms
begin_ms, end_ms = end_ms, begin_ms if begin_ms > end_ms
end_ms = begin_ms + 1 if begin_ms == end_ms
end
[begin_ms, end_ms]
end
def merge_section_ranges ranges
sorted_ranges = ranges.sort_by { |begin_ms, end_ms| [begin_ms, end_ms || Float::INFINITY] }
merged = []
sorted_ranges.each do |begin_ms, end_ms|
if merged.empty?
merged << [begin_ms, end_ms]
next
end
last_begin_ms, last_end_ms = merged[-1]
if last_end_ms.nil? || begin_ms <= last_end_ms
merged[-1] = [last_begin_ms, merge_section_end(last_end_ms, end_ms)]
else
merged << [begin_ms, end_ms]
end
end
merged
end
def merge_section_end left_end_ms, right_end_ms
return nil if left_end_ms.nil? || right_end_ms.nil?
[left_end_ms, right_end_ms].max
end
def find_or_create_by_tag_name! locale, name, category:
language_code = locale.language_code
name = name.to_s.strip
tn = TagName.find_or_create_by!(language_code:, name:) do
_1.script_code = locale.script_code
_1.primary_flg = true
end
tag = tn.tag
return tag if tag
tag = Tag.create!(tag_name_id: tn.id, category:)
tn.update!(tag:)
generate_tag_names!(locale, tag, tn)
tag.association(:tag_names).reset
tag
rescue ActiveRecord::RecordNotUnique
retry
end
def merge_tags! target_tag, source_tags, created_by_user: nil
target_tag => Tag
affected_post_ids = Set.new
Tag.transaction do
TagVersioning.ensure_snapshot!(target_tag, created_by_user:)
Array(source_tags).compact.uniq.each do |source_tag|
source_tag => Tag
next if source_tag == target_tag
TagVersioning.ensure_snapshot!(source_tag, created_by_user:)
source_tag.post_tags.find_each do |source_pt|
post_id = source_pt.post_id
affected_post_ids << post_id
source_pt.destroy!
unless PostTag.exists?(post_id:, tag: target_tag)
PostTag.create!(post_id:, tag: target_tag)
end
end
source_tag_name = source_tag.tag_name('ja')
if source_tag_name.wiki_page.present?
raise ActiveRecord::RecordInvalid.new(source_tag_name)
end
TagVersioning.record!(source_tag, event_type: :discard, created_by_user:)
source_tag.tag_names.update_all(tag_id: target_tag.id, primary_flg: false,
updated_at: Time.current)
source_tag.destroy!
source_tag_name.update_columns(canonical_id: target_tag.tag_name_id,
updated_at: Time.current)
TagVersioning.record!(target_tag, event_type: :update, created_by_user:)
end
Post.where(id: affected_post_ids.to_a).find_each do |post|
PostVersionRecorder.ensure_snapshot!(post, created_by_user:)
PostVersionRecorder.record!(post:, event_type: :update, created_by_user:)
end
# 投稿件数を再集計
target_tag.update_columns(post_count: PostTag.where(tag: target_tag).count)
end
target_tag.reload
end
def time_to_ms! str, tag_name:
match =
case str
when /\A(?<seconds>\d+)(?:\.(?<ms>\d{1,3}))?\z/
{ hours: nil, minutes: nil, seconds: Regexp.last_match[:seconds],
ms: Regexp.last_match[:ms] }
when /\A(?<minutes>\d+):(?<seconds>[0-5]?\d)(?:\.(?<ms>\d{1,3}))?\z/
{ hours: nil, minutes: Regexp.last_match[:minutes],
seconds: Regexp.last_match[:seconds],
ms: Regexp.last_match[:ms] }
when /\A(?<hours>\d+):(?<minutes>[0-5]?\d):(?<seconds>[0-5]?\d)(?:\.(?<ms>\d{1,3}))?\z/
{ hours: Regexp.last_match[:hours],
minutes: Regexp.last_match[:minutes],
seconds: Regexp.last_match[:seconds],
ms: Regexp.last_match[:ms] }
end
raise SectionLiteralParseError.new(tag_name, str) unless match
total_s = match[:seconds].to_i
total_s += match[:minutes].to_i * 60 if match[:minutes]
total_s += match[:hours].to_i * 3_600 if match[:hours]
total_s * 1_000 + match[:ms].to_s.ljust(3, '0')[0, 3].to_i
end
private
def generate_tag_names! locale, tag, base_tag_name
ApplicationRecord.transaction do
locales =
Locale
.where(deprecated_at: nil)
.where.not(language_code: locale.language_code)
.order(:language_code, :created_at, :script_code)
.uniq { _1.language_code }
locales.each do |locale|
language_code = locale.language_code
script_code = locale.script_code
TagName.create!(tag_id: tag.id,
language_code:,
name: TagName.generate_name(locale, tag, base_tag_name),
script_code:,
primary_flg: true,
auto_generated: true,
canonical_id: nil)
end
end
end
end
private private
def tag_names_must_be_valid def tag_names_must_be_valid
@@ -334,30 +387,4 @@ class Tag < ApplicationRecord
errors.add :category, 'ニジラーと紐づいてゐるタグはニジラー・カテゴリである必要があります.' errors.add :category, 'ニジラーと紐づいてゐるタグはニジラー・カテゴリである必要があります.'
end end
end end
def self.time_to_ms! str, tag_name:
match =
case str
when /\A(?<seconds>\d+)(?:\.(?<ms>\d{1,3}))?\z/
{ hours: nil, minutes: nil, seconds: Regexp.last_match[:seconds],
ms: Regexp.last_match[:ms] }
when /\A(?<minutes>\d+):(?<seconds>[0-5]?\d)(?:\.(?<ms>\d{1,3}))?\z/
{ hours: nil, minutes: Regexp.last_match[:minutes],
seconds: Regexp.last_match[:seconds],
ms: Regexp.last_match[:ms] }
when /\A(?<hours>\d+):(?<minutes>[0-5]?\d):(?<seconds>[0-5]?\d)(?:\.(?<ms>\d{1,3}))?\z/
{ hours: Regexp.last_match[:hours],
minutes: Regexp.last_match[:minutes],
seconds: Regexp.last_match[:seconds],
ms: Regexp.last_match[:ms] }
end
raise SectionLiteralParseError.new(tag_name, str) unless match
total_s = match[:seconds].to_i
total_s += match[:minutes].to_i * 60 if match[:minutes]
total_s += match[:hours].to_i * 3_600 if match[:hours]
total_s * 1_000 + match[:ms].to_s.ljust(3, '0')[0, 3].to_i
end
end end
+1 -1
ファイルの表示
@@ -32,7 +32,7 @@ class TagName < ApplicationRecord
}.uniq }.uniq
end end
def self.generate_name locale, tag, name def self.generate_name locale, tag, base_tag_name
# TODO: 言語ごとの自動命名ロジック完成したら書く. # TODO: 言語ごとの自動命名ロジック完成したら書く.
"Tag_##{ tag.id }" "Tag_##{ tag.id }"
+10 -7
ファイルの表示
@@ -17,22 +17,23 @@ RSpec.describe Locale, type: :model do
second = create(:tag, primary_name: 'second_existing_tag') second = create(:tag, primary_name: 'second_existing_tag')
allow(TagName).to receive(:generate_name).and_call_original allow(TagName).to receive(:generate_name).and_call_original
allow(TagName).to receive(:generate_name) allow(TagName).to receive(:generate_name)
.with(kind_of(described_class), first, primary_tag_name_for(first, 'ja').name) .with(kind_of(described_class), first, primary_tag_name_for(first, 'ja'))
.and_return('name_from_generator') .and_return('name_from_generator')
locale = create_french_locale! locale = create_french_locale!
expect(TagName).to have_received(:generate_name) expect(TagName).to have_received(:generate_name)
.with(locale, first, primary_tag_name_for(first, 'ja').name) .with(locale, first, primary_tag_name_for(first, 'ja'))
expect(TagName).to have_received(:generate_name) expect(TagName).to have_received(:generate_name)
.with(locale, second, primary_tag_name_for(second, 'ja').name) .with(locale, second, primary_tag_name_for(second, 'ja'))
expect(first.tag_names.find_by!(language_code: 'fr', primary_flg: true)) expect(first.tag_names.find_by!(language_code: 'fr', primary_flg: true))
.to have_attributes(name: 'name_from_generator', tag_id: first.id, .to have_attributes(name: 'name_from_generator', tag_id: first.id,
language_code: 'fr', script_code: 'Latn', language_code: 'fr', script_code: 'Latn',
primary_flg: true) primary_flg: true, auto_generated: true)
expect(second.tag_names.find_by!(language_code: 'fr', primary_flg: true)) expect(second.tag_names.find_by!(language_code: 'fr', primary_flg: true))
.to have_attributes(tag_id: second.id, language_code: 'fr', .to have_attributes(tag_id: second.id, language_code: 'fr',
script_code: 'Latn', primary_flg: true) script_code: 'Latn', primary_flg: true,
auto_generated: true)
expect(TagName.where(language_code: 'fr', primary_flg: true, expect(TagName.where(language_code: 'fr', primary_flg: true,
tag_id: [first.id, second.id]).count).to eq(2) tag_id: [first.id, second.id]).count).to eq(2)
end end
@@ -48,7 +49,8 @@ RSpec.describe Locale, type: :model do
expect(TagName.where(tag_id: tag.id, language_code: 'fr', primary_flg: true)) expect(TagName.where(tag_id: tag.id, language_code: 'fr', primary_flg: true))
.to contain_exactly(existing) .to contain_exactly(existing)
expect(existing.reload).to have_attributes( expect(existing.reload).to have_attributes(
tag_id: tag.id, language_code: 'fr', script_code: 'Latn', primary_flg: true) tag_id: tag.id, language_code: 'fr', script_code: 'Latn',
primary_flg: true, auto_generated: false)
end end
it 'creates a primary name when the language has only an alias' do it 'creates a primary name when the language has only an alias' do
@@ -65,7 +67,8 @@ RSpec.describe Locale, type: :model do
language_code: 'fr', script_code: 'Latn', primary_flg: false) language_code: 'fr', script_code: 'Latn', primary_flg: false)
generated = TagName.find_by!(tag_id: tag.id, language_code: 'fr', primary_flg: true) generated = TagName.find_by!(tag_id: tag.id, language_code: 'fr', primary_flg: true)
expect(generated).to have_attributes(tag_id: tag.id, language_code: 'fr', expect(generated).to have_attributes(tag_id: tag.id, language_code: 'fr',
script_code: 'Latn', primary_flg: true) script_code: 'Latn', primary_flg: true,
auto_generated: true)
expect(TagName.where(tag_id: tag.id, language_code: 'fr', primary_flg: true).count).to eq(1) expect(TagName.where(tag_id: tag.id, language_code: 'fr', primary_flg: true).count).to eq(1)
end end
end end
+6 -6
ファイルの表示
@@ -31,14 +31,14 @@ RSpec.describe TagNameSanitisationRule, type: :model do
describe '.apply!' do describe '.apply!' do
before do before do
described_class.create!(priority: 10, source_pattern: '_', replacement: '') described_class.create!(priority: 10, source_pattern: 'foo_', replacement: 'foo')
end end
context 'when only another language has the sanitised name' do context 'when only another language has the sanitised name' do
include_context 'English locale' include_context 'English locale'
it 'keeps both names when sanitisation produces a cross-language match' do it 'keeps both names when sanitisation produces a cross-language match' do
japanese = create(:tag_name, name: 'foobar') nipponese = create(:tag_name, name: 'foobar')
english = create(:tag_name, name: 'temporary', english = create(:tag_name, name: 'temporary',
language_code: 'en', script_code: 'Latn') language_code: 'en', script_code: 'Latn')
english.update_columns(name: 'foo_bar') english.update_columns(name: 'foo_bar')
@@ -46,11 +46,11 @@ RSpec.describe TagNameSanitisationRule, type: :model do
expect { described_class.apply! }.not_to change(TagName, :count) expect { described_class.apply! }.not_to change(TagName, :count)
expect(english.reload).to have_attributes(name: 'foobar', language_code: 'en') expect(english.reload).to have_attributes(name: 'foobar', language_code: 'en')
expect(japanese.reload).to have_attributes(name: 'foobar', language_code: 'ja') expect(nipponese.reload).to have_attributes(name: 'foobar', language_code: 'ja')
end end
it 'renames without merging tags or deleting either language identity' do it 'renames without merging tags or deleting either language identity' do
japanese = create(:tag, primary_name: 'foobar') nipponese = create(:tag, primary_name: 'foobar')
english_name = create(:tag_name, name: 'temporary', english_name = create(:tag_name, name: 'temporary',
language_code: 'en', script_code: 'Latn') language_code: 'en', script_code: 'Latn')
english = create(:tag, primary_tag_name: english_name) english = create(:tag, primary_tag_name: english_name)
@@ -60,8 +60,8 @@ RSpec.describe TagNameSanitisationRule, type: :model do
expect(english_name.reload).to have_attributes( expect(english_name.reload).to have_attributes(
name: 'foobar', language_code: 'en', tag_id: english.id) name: 'foobar', language_code: 'en', tag_id: english.id)
expect(primary_tag_name_for(japanese.reload, 'ja')).to have_attributes( expect(primary_tag_name_for(nipponese.reload, 'ja')).to have_attributes(
name: 'foobar', language_code: 'ja', tag_id: japanese.id) name: 'foobar', language_code: 'ja', tag_id: nipponese.id)
expect(primary_tag_name_for(english.reload, 'en')).to eq(english_name) expect(primary_tag_name_for(english.reload, 'en')).to eq(english_name)
end end
end end
+7 -16
ファイルの表示
@@ -20,7 +20,7 @@ RSpec.describe TagName, type: :model do
expect(duplicate.errors.of_kind?(:name, :taken)).to be(true) expect(duplicate.errors.of_kind?(:name, :taken)).to be(true)
end end
it 'creates Japanese factory names without requiring a tag' do it 'creates Nipponese factory names without requiring a tag' do
name = create(:tag_name) name = create(:tag_name)
expect(name.reload).to have_attributes( expect(name.reload).to have_attributes(
@@ -74,15 +74,6 @@ RSpec.describe TagName, type: :model do
.to eq(['detached_alias']) .to eq(['detached_alias'])
end end
it 'leaves an alias unchanged when its language has no primary' do
tag = create(:tag, primary_name: '日本語のみ')
create(:tag_name, :alias, tag:, name: 'orphan_english_alias',
language_code: 'en', script_code: 'Latn')
expect(described_class.canonicalise(locale, ['orphan_english_alias']))
.to eq(['orphan_english_alias'])
end
it 'resolves the primary name of the alias language on the same tag' do it 'resolves the primary name of the alias language on the same tag' do
tag = create(:tag, primary_name: '日本語正本') tag = create(:tag, primary_name: '日本語正本')
english_primary = create(:tag_name, tag:, name: 'english_primary', english_primary = create(:tag_name, tag:, name: 'english_primary',
@@ -102,18 +93,18 @@ RSpec.describe TagName, type: :model do
end end
it 'resolves only aliases in the requested language' do it 'resolves only aliases in the requested language' do
japanese = create(:tag, primary_name: 'japanese_canonical') nipponese = create(:tag, primary_name: 'nipponese_canonical')
english_name = create(:tag_name, name: 'english_canonical', english_name = create(:tag_name, name: 'english_canonical',
language_code: 'en', script_code: 'Latn') language_code: 'en', script_code: 'Latn')
english = create(:tag, primary_tag_name: english_name) english = create(:tag, primary_tag_name: english_name)
japanese_alias = create(:tag_name, :alias, name: 'shared_alias', nipponese_alias = create(:tag_name, :alias, name: 'shared_alias',
tag: japanese) tag: nipponese)
english_alias = create(:tag_name, :alias, name: 'shared_alias', english_alias = create(:tag_name, :alias, name: 'shared_alias',
tag: english, tag: english,
language_code: 'en', script_code: 'Latn') language_code: 'en', script_code: 'Latn')
expect(japanese_alias.reload).to have_attributes( expect(nipponese_alias.reload).to have_attributes(
tag_id: japanese.id, tag_id: nipponese.id,
primary_flg: false, language_code: 'ja') primary_flg: false, language_code: 'ja')
expect(english_alias.reload).to have_attributes( expect(english_alias.reload).to have_attributes(
tag_id: english.id, tag_id: english.id,
@@ -121,7 +112,7 @@ RSpec.describe TagName, type: :model do
expect(described_class.canonicalise(locale, ['shared_alias'])) expect(described_class.canonicalise(locale, ['shared_alias']))
.to eq(['english_canonical']) .to eq(['english_canonical'])
expect(described_class.canonicalise(Locale.nipponese, ['shared_alias'])) expect(described_class.canonicalise(Locale.nipponese, ['shared_alias']))
.to eq(['japanese_canonical']) .to eq(['nipponese_canonical'])
end end
end end
end end
+50 -34
ファイルの表示
@@ -28,22 +28,21 @@ RSpec.describe Tag, type: :model do
it 'canonicalises aliases in the supplied language only' do it 'canonicalises aliases in the supplied language only' do
Language.find_or_create_by!(code: 'en') { _1.name = 'English' } Language.find_or_create_by!(code: 'en') { _1.name = 'English' }
Script.find_or_create_by!(code: 'Latn') { _1.name = 'Latin' } Script.find_or_create_by!(code: 'Latn') { _1.name = 'Latin' }
Locale.insert_all!([ nipponese = create(:tag, primary_name: 'nipponese_canonical')
{ code: 'en', language_code: 'en', script_code: 'Latn',
name: 'English', created_at: Time.current }]) unless Locale.exists?(code: 'en')
english_locale = Locale.find('en')
japanese = create(:tag, primary_name: 'japanese_canonical')
english_name = create(:tag_name, name: 'english_canonical', english_name = create(:tag_name, name: 'english_canonical',
language_code: 'en', script_code: 'Latn') language_code: 'en', script_code: 'Latn')
english = create(:tag, primary_tag_name: english_name) english = create(:tag, primary_tag_name: english_name)
japanese_alias = create(:tag_name, :alias, name: 'shared_alias', create(:tag_name, tag: english, name: 'english_in_nipponese')
tag: japanese) english_locale = Locale.create!(
code: 'en', language_code: 'en', script_code: 'Latn', name: 'English')
nipponese_alias = create(:tag_name, :alias, name: 'shared_alias',
tag: nipponese)
english_alias = create(:tag_name, :alias, name: 'shared_alias', english_alias = create(:tag_name, :alias, name: 'shared_alias',
tag: english, tag: english,
language_code: 'en', script_code: 'Latn') language_code: 'en', script_code: 'Latn')
expect(japanese_alias.reload).to have_attributes( expect(nipponese_alias.reload).to have_attributes(
tag_id: japanese.id, tag_id: nipponese.id,
primary_flg: false, language_code: 'ja') primary_flg: false, language_code: 'ja')
expect(english_alias.reload).to have_attributes( expect(english_alias.reload).to have_attributes(
tag_id: english.id, tag_id: english.id,
@@ -53,7 +52,7 @@ RSpec.describe Tag, type: :model do
with_tagme: false, with_no_deerjikist: false)).to eq([english]) with_tagme: false, with_no_deerjikist: false)).to eq([english])
expect(described_class.normalise_tags!( expect(described_class.normalise_tags!(
Locale.nipponese, ['shared_alias'], Locale.nipponese, ['shared_alias'],
with_tagme: false, with_no_deerjikist: false)).to eq([japanese]) with_tagme: false, with_no_deerjikist: false)).to eq([nipponese])
end end
it 'rejects deprecated tags when deny_deprecated is enabled' do it 'rejects deprecated tags when deny_deprecated is enabled' do
@@ -228,21 +227,46 @@ RSpec.describe Tag, type: :model do
expect(tag.category).to eq('character') expect(tag.category).to eq('character')
end end
it 'uses the English primary as the source for a generated Nipponese name' do
allow(TagName).to receive(:generate_name).and_return('generated_nipponese')
tag = described_class.find_or_create_by_tag_name!(
locale, 'english_origin', category: :general)
expect(TagName.where(tag:, language_code: 'en', primary_flg: true))
.to contain_exactly(have_attributes(
name: 'english_origin', auto_generated: false))
expect(TagName.where(tag:, language_code: 'ja', primary_flg: true))
.to contain_exactly(have_attributes(
name: 'generated_nipponese', auto_generated: true))
source_tag_name = TagName.find_by!(tag:, language_code: 'en', primary_flg: true)
expect(TagName).to have_received(:generate_name)
.with(Locale.nipponese, tag, source_tag_name)
end
it 'gives a new tag one primary name for every active language' do
tag = described_class.find_or_create_by_tag_name!(
Locale.nipponese, 'new_multilingual_tag', category: :general)
expect(TagName.where(tag:, language_code: 'ja', primary_flg: true).count).to eq(1)
expect(TagName.where(tag:, language_code: 'en', primary_flg: true).count).to eq(1)
end
it 'creates separate tag identities for the same name in different languages' do it 'creates separate tag identities for the same name in different languages' do
japanese = described_class.find_or_create_by_tag_name!( nipponese = described_class.find_or_create_by_tag_name!(
Locale.nipponese, 'same_name', category: :general) Locale.nipponese, 'same_name', category: :general)
english = described_class.find_or_create_by_tag_name!( english = described_class.find_or_create_by_tag_name!(
locale, 'same_name', category: :character) locale, 'same_name', category: :character)
expect(english).not_to eq(japanese) expect(english).not_to eq(nipponese)
expect(primary_tag_name_for(english, 'en')).to have_attributes( expect(primary_tag_name_for(english, 'en')).to have_attributes(
name: 'same_name', tag_id: english.id, language_code: 'en', primary_flg: true) name: 'same_name', tag_id: english.id, language_code: 'en', primary_flg: true)
expect(primary_tag_name_for(japanese, 'ja')).to have_attributes( expect(primary_tag_name_for(nipponese, 'ja')).to have_attributes(
name: 'same_name', tag_id: japanese.id, language_code: 'ja', primary_flg: true) name: 'same_name', tag_id: nipponese.id, language_code: 'ja', primary_flg: true)
expect(described_class.find_or_create_by_tag_name!( expect(described_class.find_or_create_by_tag_name!(
locale, 'same_name', category: :general)).to eq(english) locale, 'same_name', category: :general)).to eq(english)
expect(described_class.find_or_create_by_tag_name!( expect(described_class.find_or_create_by_tag_name!(
Locale.nipponese, 'same_name', category: :general)).to eq(japanese) Locale.nipponese, 'same_name', category: :general)).to eq(nipponese)
end end
it 'preserves the V1 representative when looking up another primary language' do it 'preserves the V1 representative when looking up another primary language' do
@@ -335,33 +359,25 @@ RSpec.describe Tag, type: :model do
include_context 'English locale' include_context 'English locale'
it 'keeps the target primary and moves source names as aliases' do it 'keeps the target primary and moves source names as aliases' do
english_primary = create(:tag_name, tag: target_tag, english_primary = primary_tag_name_for(target_tag, 'en')
name: 'target_english', language_code: 'en', script_code: 'Latn') source_primary = primary_tag_name_for(source_tag, 'en')
source_primary = create(:tag_name, tag: source_tag,
name: 'source_english', language_code: 'en', script_code: 'Latn')
source_alias = create(:tag_name, :alias, tag: source_tag, source_alias = create(:tag_name, :alias, tag: source_tag,
name: 'source_english_alias', language_code: 'en', script_code: 'Latn') name: 'source_english_alias', language_code: 'en', script_code: 'Latn')
expect([english_primary, source_primary]).to all(have_attributes(
primary_flg: true, auto_generated: true))
described_class.merge_tags!(target_tag, [source_tag]) described_class.merge_tags!(target_tag, [source_tag])
expect(primary_tag_name_for(target_tag.reload, 'en')).to eq(english_primary) expect(primary_tag_name_for(target_tag.reload, 'en')).to eq(english_primary)
expect(TagName.where(tag: target_tag, language_code: 'en', primary_flg: true))
.to contain_exactly(english_primary)
expect([source_primary.reload, source_alias.reload]).to all(have_attributes( expect([source_primary.reload, source_alias.reload]).to all(have_attributes(
tag_id: target_tag.id, language_code: 'en', primary_flg: false)) tag_id: target_tag.id, language_code: 'en', primary_flg: false))
end expect(TagName.where(tag: target_tag, language_code: 'ja', primary_flg: true))
.to contain_exactly(primary_tag_name_for(target_tag, 'ja'))
it 'inherits a source primary when the target has no name in that language' do expect(source_tag_name.reload).to have_attributes(
source_primary = create(:tag_name, tag: source_tag, tag_id: target_tag.id, language_code: 'ja', primary_flg: false)
name: 'inherited_english', language_code: 'en', script_code: 'Latn')
source_alias = create(:tag_name, :alias, tag: source_tag,
name: 'inherited_alias', language_code: 'en', script_code: 'Latn')
described_class.merge_tags!(target_tag, [source_tag])
expect(primary_tag_name_for(target_tag.reload, 'en')).to eq(source_primary)
expect(source_primary.reload).to have_attributes(
tag_id: target_tag.id, language_code: 'en', primary_flg: true)
expect(source_alias.reload).to have_attributes(
tag_id: target_tag.id, language_code: 'en', primary_flg: false)
end end
end end
+20 -20
ファイルの表示
@@ -22,7 +22,7 @@ RSpec.describe 'Locale propagation on write paths', type: :request do
let(:locale_params) { requested_locale ? { locale: requested_locale } : { } } let(:locale_params) { requested_locale ? { locale: requested_locale } : { } }
let(:expected_locale) { requested_locale ? locale : Locale.nipponese } let(:expected_locale) { requested_locale ? locale : Locale.nipponese }
it 'creates post tags in the requested language or Japanese fallback' do it 'creates post tags in the requested language or Nipponese fallback' do
post '/posts', params: locale_params.merge( post '/posts', params: locale_params.merge(
title: 'Locale post', url: 'https://example.com/locale-post', title: 'Locale post', url: 'https://example.com/locale-post',
tags: 'locale_post_tag', parent_post_ids: '') tags: 'locale_post_tag', parent_post_ids: '')
@@ -32,7 +32,7 @@ RSpec.describe 'Locale propagation on write paths', type: :request do
expect(Post.find(json.fetch('id')).tags).to include(tag) expect(Post.find(json.fetch('id')).tags).to include(tag)
end end
it 'updates post tags in the requested language or Japanese fallback' do it 'updates post tags in the requested language or Nipponese fallback' do
record = create(:post) record = create(:post)
PostVersionRecorder.record!(post: record, event_type: :create, created_by_user: member) PostVersionRecorder.record!(post: record, event_type: :create, created_by_user: member)
@@ -110,8 +110,8 @@ RSpec.describe 'Locale propagation on write paths', type: :request do
create(:tag_name, name: 'shared_name', language_code: 'en', script_code: 'Latn') create(:tag_name, name: 'shared_name', language_code: 'en', script_code: 'Latn')
end end
let!(:english_tag) { create(:tag, primary_tag_name: english_name, category: :material) } let!(:english_tag) { create(:tag, primary_tag_name: english_name, category: :material) }
let!(:japanese_tag) do let!(:nipponese_tag) do
create(:tag, primary_name: 'temporary_japanese', category: :general).tap do |tag| create(:tag, primary_name: 'temporary_nipponese', category: :general).tap do |tag|
# Isolate lookup from the separately tested uniqueness validation. # Isolate lookup from the separately tested uniqueness validation.
primary_tag_name_for(tag, 'ja').update_columns(name: 'shared_name') primary_tag_name_for(tag, 'ja').update_columns(name: 'shared_name')
end end
@@ -125,9 +125,9 @@ RSpec.describe 'Locale propagation on write paths', type: :request do
expect(response).to have_http_status(:created), response.body expect(response).to have_http_status(:created), response.body
record = Post.find(json.fetch('id')) record = Post.find(json.fetch('id'))
expect(record.tags).to include(english_tag) expect(record.tags).to include(english_tag)
expect(record.tags).not_to include(japanese_tag) expect(record.tags).not_to include(nipponese_tag)
expect(english_tag.reload.category).to eq('material') expect(english_tag.reload.category).to eq('material')
expect(japanese_tag.reload.category).to eq('general') expect(nipponese_tag.reload.category).to eq('general')
end end
it 'updates the post using the English identity' do it 'updates the post using the English identity' do
@@ -140,7 +140,7 @@ RSpec.describe 'Locale propagation on write paths', type: :request do
expect(response).to have_http_status(:ok), response.body expect(response).to have_http_status(:ok), response.body
expect(record.reload.tags).to include(english_tag) expect(record.reload.tags).to include(english_tag)
expect(record.tags).not_to include(japanese_tag) expect(record.tags).not_to include(nipponese_tag)
end end
it 'resolves the English material tag' do it 'resolves the English material tag' do
@@ -149,7 +149,7 @@ RSpec.describe 'Locale propagation on write paths', type: :request do
expect(response).to have_http_status(:created), response.body expect(response).to have_http_status(:created), response.body
expect(Material.find(json.fetch('id')).tag).to eq(english_tag) expect(Material.find(json.fetch('id')).tag).to eq(english_tag)
expect(Material.where(tag: japanese_tag)).to be_empty expect(Material.where(tag: nipponese_tag)).to be_empty
end end
it 'resolves the English parent tag' do it 'resolves the English parent tag' do
@@ -182,16 +182,16 @@ RSpec.describe 'Locale propagation on write paths', type: :request do
end end
let!(:tag) { create(:tag, primary_tag_name: english_name) } let!(:tag) { create(:tag, primary_tag_name: english_name) }
it 'allows a rename to a name already used in Japanese' do it 'allows a rename to a name already used in Nipponese' do
japanese = create(:tag, primary_name: 'rename_target') nipponese = create(:tag, primary_name: 'rename_target')
patch "/tags/#{ tag.id }", params: { locale: 'en', name: 'rename_target' } patch "/tags/#{ tag.id }", params: { locale: 'en', name: 'rename_target' }
expect(response).to have_http_status(:ok), response.body expect(response).to have_http_status(:ok), response.body
expect(primary_tag_name_for(tag.reload, 'en')).to have_attributes( expect(primary_tag_name_for(tag.reload, 'en')).to have_attributes(
name: 'rename_target', language_code: 'en', tag_id: tag.id) name: 'rename_target', language_code: 'en', tag_id: tag.id)
expect(primary_tag_name_for(japanese.reload, 'ja')).to have_attributes( expect(primary_tag_name_for(nipponese.reload, 'ja')).to have_attributes(
name: 'rename_target', language_code: 'ja', tag_id: japanese.id) name: 'rename_target', language_code: 'ja', tag_id: nipponese.id)
end end
it 'creates aliases in the requested language' do it 'creates aliases in the requested language' do
@@ -210,11 +210,11 @@ RSpec.describe 'Locale propagation on write paths', type: :request do
end end
it 'does not take an alias from another language' do it 'does not take an alias from another language' do
japanese = create(:tag, primary_name: 'japanese_owner') nipponese = create(:tag, primary_name: 'nipponese_owner')
japanese_alias = create(:tag_name, :alias, name: 'shared_alias', nipponese_alias = create(:tag_name, :alias, name: 'shared_alias',
tag: japanese) tag: nipponese)
expect(japanese_alias.reload).to have_attributes( expect(nipponese_alias.reload).to have_attributes(
tag_id: japanese.id, tag_id: nipponese.id,
primary_flg: false, language_code: 'ja') primary_flg: false, language_code: 'ja')
put "/tags/#{ tag.id }", params: { put "/tags/#{ tag.id }", params: {
@@ -223,15 +223,15 @@ RSpec.describe 'Locale propagation on write paths', type: :request do
aliases: 'shared_alias', parent_tags: '' } aliases: 'shared_alias', parent_tags: '' }
expect(response).to have_http_status(:ok), response.body expect(response).to have_http_status(:ok), response.body
expect(japanese_alias.reload).to have_attributes( expect(nipponese_alias.reload).to have_attributes(
tag_id: japanese.id, tag_id: nipponese.id,
primary_flg: false, language_code: 'ja') primary_flg: false, language_code: 'ja')
expect(TagName.find_by!(language_code: 'en', name: 'shared_alias')) expect(TagName.find_by!(language_code: 'en', name: 'shared_alias'))
.to have_attributes( .to have_attributes(
tag_id: tag.id, script_code: 'Latn', tag_id: tag.id, script_code: 'Latn',
primary_flg: false, language_code: 'en') primary_flg: false, language_code: 'en')
expect(TagName.where(name: 'shared_alias').pluck(:language_code, :tag_id)) expect(TagName.where(name: 'shared_alias').pluck(:language_code, :tag_id))
.to contain_exactly(['ja', japanese.id], ['en', tag.id]) .to contain_exactly(['ja', nipponese.id], ['en', tag.id])
end end
end end
end end
+10 -10
ファイルの表示
@@ -17,16 +17,16 @@ RSpec.describe PostCreatePlan do
english_name = create(:tag_name, name: 'shared_name', english_name = create(:tag_name, name: 'shared_name',
language_code: 'en', script_code: 'Latn') language_code: 'en', script_code: 'Latn')
english = create(:tag, primary_tag_name: english_name, category: :character) english = create(:tag, primary_tag_name: english_name, category: :character)
japanese = create(:tag, primary_name: 'temporary_japanese', category: :general) nipponese = create(:tag, primary_name: 'temporary_nipponese', category: :general)
# The DB permits this identity; validation has its own contract spec. # The DB permits this identity; validation has its own contract spec.
primary_tag_name_for(japanese, 'ja').update_columns(name: 'shared_name') primary_tag_name_for(nipponese, 'ja').update_columns(name: 'shared_name')
english_parent_name = create(:tag_name, name: 'english_parent', english_parent_name = create(:tag_name, name: 'english_parent',
language_code: 'en', script_code: 'Latn') language_code: 'en', script_code: 'Latn')
english_parent = create(:tag, primary_tag_name: english_parent_name, english_parent = create(:tag, primary_tag_name: english_parent_name,
category: :material) category: :material)
japanese_parent = create(:tag, primary_name: 'japanese_parent', category: :general) nipponese_parent = create(:tag, primary_name: 'nipponese_parent', category: :general)
TagImplication.create!(tag: english, parent_tag: english_parent) TagImplication.create!(tag: english, parent_tag: english_parent)
TagImplication.create!(tag: japanese, parent_tag: japanese_parent) TagImplication.create!(tag: nipponese, parent_tag: nipponese_parent)
plan = described_class.new(attributes: { tags: 'shared_name' }).build!(locale) plan = described_class.new(attributes: { tags: 'shared_name' }).build!(locale)
@@ -35,22 +35,22 @@ RSpec.describe PostCreatePlan do
expect(plan[:post_tag_specs]).to include( expect(plan[:post_tag_specs]).to include(
{ name: primary_tag_name_for(english_parent, 'en').name, category: :material }) { name: primary_tag_name_for(english_parent, 'en').name, category: :material })
expect(plan[:post_tag_specs].pluck(:name)) expect(plan[:post_tag_specs].pluck(:name))
.not_to include(primary_tag_name_for(japanese_parent, 'ja').name) .not_to include(primary_tag_name_for(nipponese_parent, 'ja').name)
end end
it 'resolves aliases within the requested language' do it 'resolves aliases within the requested language' do
japanese = create(:tag, primary_name: 'japanese_canonical') nipponese = create(:tag, primary_name: 'nipponese_canonical')
english_name = create(:tag_name, name: 'english_canonical', english_name = create(:tag_name, name: 'english_canonical',
language_code: 'en', script_code: 'Latn') language_code: 'en', script_code: 'Latn')
english = create(:tag, primary_tag_name: english_name, category: :character) english = create(:tag, primary_tag_name: english_name, category: :character)
japanese_alias = create(:tag_name, :alias, name: 'shared_alias', nipponese_alias = create(:tag_name, :alias, name: 'shared_alias',
tag: japanese) tag: nipponese)
english_alias = create(:tag_name, :alias, name: 'shared_alias', english_alias = create(:tag_name, :alias, name: 'shared_alias',
tag: english, tag: english,
language_code: 'en', script_code: 'Latn') language_code: 'en', script_code: 'Latn')
expect(japanese_alias.reload).to have_attributes( expect(nipponese_alias.reload).to have_attributes(
tag_id: japanese.id, tag_id: nipponese.id,
primary_flg: false, language_code: 'ja') primary_flg: false, language_code: 'ja')
expect(english_alias.reload).to have_attributes( expect(english_alias.reload).to have_attributes(
tag_id: english.id, tag_id: english.id,
+3 -6
ファイルの表示
@@ -2,15 +2,12 @@ require 'rails_helper'
RSpec.describe TagVersionRecorder do RSpec.describe TagVersionRecorder do
let(:user) { create_member_user! } let(:user) { create_member_user! }
let(:tag) { create(:tag, primary_name: '日本語名') } let!(:tag) { create(:tag, primary_name: '日本語名') }
include_context 'English locale'
before do before do
Language.insert_all!([{ code: 'en', name: 'English', created_at: Time.current }])
Script.insert_all!([{ code: 'Latn', name: 'Latin', created_at: Time.current }])
Locale.insert_all!([{ code: 'en', language_code: 'en', script_code: 'Latn',
name: 'English', created_at: Time.current }])
create(:tag_name, :alias, tag:, name: '別名') create(:tag_name, :alias, tag:, name: '別名')
create(:tag_name, tag:, language_code: 'en', script_code: 'Latn', name: 'English name') primary_tag_name_for(tag, 'en').update!(name: 'English name', auto_generated: false)
create(:tag_name, :alias, tag:, language_code: 'en', script_code: 'Latn', create(:tag_name, :alias, tag:, language_code: 'en', script_code: 'Latn',
name: 'English alias') name: 'English alias')
end end
+4 -6
ファイルの表示
@@ -2,12 +2,10 @@ RSpec.shared_context 'English locale' do
let!(:locale) do let!(:locale) do
Language.find_or_create_by!(code: 'en') { _1.name = 'English' } Language.find_or_create_by!(code: 'en') { _1.name = 'English' }
Script.find_or_create_by!(code: 'Latn') { _1.name = 'Latin' } Script.find_or_create_by!(code: 'Latn') { _1.name = 'Latin' }
unless Locale.exists?(code: 'en') Locale.find_or_create_by!(code: 'en') do |record|
# Reference data only: do not generate names for unrelated existing tags. record.language_code = 'en'
Locale.insert_all!([ record.script_code = 'Latn'
{ code: 'en', language_code: 'en', script_code: 'Latn', record.name = 'English'
name: 'English', created_at: Time.current }])
end end
Locale.find('en')
end end
end end