Skip to content

Commit b2aa424

Browse files
committed
Override i18n_key on ActiveRecord-derived classes
This allows creating translations for the derived classes themselves instead of polluting the base class translations. For this we need to create an ActiveModel::Name, which uses the parent class name, but derived class reference. We then override the i18n_key, but not the other ones, to override i18n lookup but keep the same parameter and route names. A test is added to ensure the behavior Fixes: #115
1 parent 0973a8f commit b2aa424

File tree

2 files changed

+63
-1
lines changed

2 files changed

+63
-1
lines changed

lib/active_type/record_extension/inheritance.rb

+18-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,24 @@ def self.add_foreign_key_option(extended_record_base_class, scope = nil, options
2828
module ClassMethods
2929

3030
def model_name
31-
extended_record_base_class.model_name
31+
@_model_name ||= begin
32+
if name
33+
# Namespace detection copied from ActiveModel::Naming
34+
namespace = extended_record_base_class.parents.detect do |n|
35+
n.respond_to?(:use_relative_model_naming?) && n.use_relative_model_naming?
36+
end
37+
# We create a Name object, with the parent class name, but self as the @klass reference
38+
# This way lookup_ancestors is invoked on the right class instead of the extended_record_base_class
39+
dup_model_name = ActiveModel::Name.new(self, namespace, extended_record_base_class.name)
40+
key = name.underscore
41+
# We fake the `i18n_key` to lookup on the derived class key
42+
# We keep the others the same to preserve parameter and route names
43+
dup_model_name.define_singleton_method(:i18n_key) { key }
44+
dup_model_name
45+
else # name is nil for the anonymous intermediate class
46+
extended_record_base_class.model_name
47+
end
48+
end
3249
end
3350

3451
def sti_name

spec/active_type/record_extension_spec.rb

+45
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,10 @@ class ExtendedRecordWithValidations < ExtendedActiveTypeRecord
137137
expect(subject.class.model_name.singular).to eq(RecordExtensionSpec::Record.model_name.singular)
138138
end
139139

140+
it 'has a different i18n_key than the base class' do
141+
expect(subject.class.model_name.i18n_key).to eq(RecordExtensionSpec::InheritingFromExtendedRecord.name.underscore)
142+
end
143+
140144
describe '#attributes' do
141145

142146
it 'returns a hash of virtual and persisted attributes' do
@@ -257,3 +261,44 @@ class ExtendedRecordWithValidations < ExtendedActiveTypeRecord
257261
end
258262

259263
end
264+
265+
describe 'i18n' do
266+
267+
around :each do |test|
268+
begin
269+
orig_backend = I18n.backend
270+
I18n.backend = I18n::Backend::KeyValue.new({})
271+
test.run
272+
ensure
273+
I18n.backend = orig_backend
274+
end
275+
end
276+
277+
describe 'translation of model name' do
278+
279+
it 'has its own I18n key' do
280+
I18n.backend.store_translations(:en, activerecord: { models: { 'record_extension_spec/extended_record': 'ExtendedRecord translation' } })
281+
expect(RecordExtensionSpec::ExtendedRecord.model_name.human).to eq('ExtendedRecord translation')
282+
end
283+
284+
it 'falls back to the I18n key of the base class if does not have its own I18n key' do
285+
I18n.backend.store_translations(:en, activerecord: { models: { 'record_extension_spec/record': 'BaseRecord translation' } })
286+
expect(RecordExtensionSpec::ExtendedRecord.model_name.human).to eq('BaseRecord translation')
287+
end
288+
289+
end
290+
291+
describe 'translation of attribute name' do
292+
293+
it 'has its own I18n key' do
294+
I18n.backend.store_translations(:en, activerecord: { attributes: { 'record_extension_spec/extended_record': { persisted_string: 'ExtendedRecord translation' } } })
295+
expect(RecordExtensionSpec::ExtendedRecord.human_attribute_name(:persisted_string)).to eq('ExtendedRecord translation')
296+
end
297+
298+
it 'falls back to the I18n key of the base class if does not have its own I18n key' do
299+
I18n.backend.store_translations(:en, activerecord: { attributes: { 'record_extension_spec/record': { persisted_string: 'BaseRecord translation' } } })
300+
expect(RecordExtensionSpec::ExtendedRecord.human_attribute_name(:persisted_string)).to eq('BaseRecord translation')
301+
end
302+
303+
end
304+
end

0 commit comments

Comments
 (0)