Skip to content

Commit

Permalink
Override i18n_key on ActiveRecord-derived classes
Browse files Browse the repository at this point in the history
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
  • Loading branch information
fsateler committed Jul 24, 2020
1 parent 0973a8f commit b2aa424
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 1 deletion.
19 changes: 18 additions & 1 deletion lib/active_type/record_extension/inheritance.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,24 @@ def self.add_foreign_key_option(extended_record_base_class, scope = nil, options
module ClassMethods

def model_name
extended_record_base_class.model_name
@_model_name ||= begin
if name
# Namespace detection copied from ActiveModel::Naming
namespace = extended_record_base_class.parents.detect do |n|
n.respond_to?(:use_relative_model_naming?) && n.use_relative_model_naming?
end
# We create a Name object, with the parent class name, but self as the @klass reference
# This way lookup_ancestors is invoked on the right class instead of the extended_record_base_class
dup_model_name = ActiveModel::Name.new(self, namespace, extended_record_base_class.name)
key = name.underscore
# We fake the `i18n_key` to lookup on the derived class key
# We keep the others the same to preserve parameter and route names
dup_model_name.define_singleton_method(:i18n_key) { key }
dup_model_name
else # name is nil for the anonymous intermediate class
extended_record_base_class.model_name
end
end
end

def sti_name
Expand Down
45 changes: 45 additions & 0 deletions spec/active_type/record_extension_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,10 @@ class ExtendedRecordWithValidations < ExtendedActiveTypeRecord
expect(subject.class.model_name.singular).to eq(RecordExtensionSpec::Record.model_name.singular)
end

it 'has a different i18n_key than the base class' do
expect(subject.class.model_name.i18n_key).to eq(RecordExtensionSpec::InheritingFromExtendedRecord.name.underscore)
end

describe '#attributes' do

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

end

describe 'i18n' do

around :each do |test|
begin
orig_backend = I18n.backend
I18n.backend = I18n::Backend::KeyValue.new({})
test.run
ensure
I18n.backend = orig_backend
end
end

describe 'translation of model name' do

it 'has its own I18n key' do
I18n.backend.store_translations(:en, activerecord: { models: { 'record_extension_spec/extended_record': 'ExtendedRecord translation' } })
expect(RecordExtensionSpec::ExtendedRecord.model_name.human).to eq('ExtendedRecord translation')
end

it 'falls back to the I18n key of the base class if does not have its own I18n key' do
I18n.backend.store_translations(:en, activerecord: { models: { 'record_extension_spec/record': 'BaseRecord translation' } })
expect(RecordExtensionSpec::ExtendedRecord.model_name.human).to eq('BaseRecord translation')
end

end

describe 'translation of attribute name' do

it 'has its own I18n key' do
I18n.backend.store_translations(:en, activerecord: { attributes: { 'record_extension_spec/extended_record': { persisted_string: 'ExtendedRecord translation' } } })
expect(RecordExtensionSpec::ExtendedRecord.human_attribute_name(:persisted_string)).to eq('ExtendedRecord translation')
end

it 'falls back to the I18n key of the base class if does not have its own I18n key' do
I18n.backend.store_translations(:en, activerecord: { attributes: { 'record_extension_spec/record': { persisted_string: 'BaseRecord translation' } } })
expect(RecordExtensionSpec::ExtendedRecord.human_attribute_name(:persisted_string)).to eq('BaseRecord translation')
end

end
end

0 comments on commit b2aa424

Please sign in to comment.