Skip to content

Commit

Permalink
Add scope config option
Browse files Browse the repository at this point in the history
Allow the entire backend to use translations only from a subset of
the translation records.
  • Loading branch information
vipera committed Dec 1, 2022
1 parent 1fe4b91 commit 7bae168
Show file tree
Hide file tree
Showing 8 changed files with 67 additions and 2 deletions.
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,16 @@ I18n::Backend::ActiveRecord.configure do |config|
end
```

The ActiveRecord backend can be configured to use a `scope` to isolate sets of translations. That way, two applications
using the backend with the same database table can use translation data independently of one another.
If configured with a scope, all data used will be limited to records with that particular scope identifier:

```ruby
I18n::Backend::ActiveRecord.configure do |config|
config.scope = 'app1' # defaults to nil, disabling scope
end
```

## Usage

You can now use `I18n.t('Your String')` to lookup translations in the database.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,5 @@ end
I18n::Backend::ActiveRecord.configure do |config|
# config.cache_translations = true # defaults to false
# config.cleanup_with_destroy = true # defaults to false
# config.scope = 'app_scope' # defaults to nil, won't be used
end
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
class <%= migration_class_name %> < ActiveRecord::Migration[<%= ActiveRecord::Migration.current_version %>]
def change
create_table :<%= table_name %> do |t|
t.string :scope
t.string :locale
t.string :key
t.text :value
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ I18n.backend = I18n::Backend::ActiveRecord.new
I18n::Backend::ActiveRecord.configure do |config|
# config.cache_translations = true # defaults to false
# config.cleanup_with_destroy = true # defaults to false
# config.scope = 'app_scope' # defaults to nil, won't be used
end
5 changes: 4 additions & 1 deletion lib/i18n/backend/active_record/configuration.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,14 @@ module I18n
module Backend
class ActiveRecord
class Configuration
attr_accessor :cleanup_with_destroy, :cache_translations
attr_accessor :cleanup_with_destroy,
:cache_translations,
:scope

def initialize
@cleanup_with_destroy = false
@cache_translations = false
@scope = nil
end
end
end
Expand Down
17 changes: 17 additions & 0 deletions lib/i18n/backend/active_record/translation.rb
Original file line number Diff line number Diff line change
Expand Up @@ -55,13 +55,24 @@ class Translation < ::ActiveRecord::Base

serialize :value
serialize :interpolations, Array
before_validation :set_scope
after_commit :invalidate_translations_cache

default_scope { scoped }

class << self
def locale(locale)
where(locale: locale.to_s)
end

def scoped
if record_scope = ActiveRecord.config.scope
where(scope: record_scope)
else
all
end
end

def lookup(keys, *separator)
column_name = connection.quote_column_name('key')
keys = Array(keys).map!(&:to_s)
Expand Down Expand Up @@ -123,6 +134,12 @@ def value=(value)
def invalidate_translations_cache
I18n.backend.reload! if I18n::Backend::ActiveRecord.config.cache_translations
end

private

def set_scope
self.scope ||= ActiveRecord.config.scope if ActiveRecord.config.scope
end
end
end
end
Expand Down
31 changes: 31 additions & 0 deletions test/active_record_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -172,4 +172,35 @@ def setup
I18n.t('foo')
end
end

class ScopeTest < I18nBackendActiveRecordTest
def setup
super

I18n::Backend::ActiveRecord.config.scope = 'scope1'
end

test 'scope config option divides translations into isolated sets' do
store_translations(:en, foo: 'foo1')
assert_equal('foo1', I18n.t(:foo))

I18n::Backend::ActiveRecord.config.scope = 'scope2'
store_translations(:en, foo: 'foo2')
assert_equal('foo2', I18n.t(:foo))

I18n::Backend::ActiveRecord.config.scope = 'scope1'
assert_equal('foo1', I18n.t(:foo))
end

test 'scope config of nil disables scope' do
store_translations(:en, bar1: 'bar1')

I18n::Backend::ActiveRecord.config.scope = 'scope2'
store_translations(:en, bar2: 'bar2')

I18n::Backend::ActiveRecord.config.scope = nil
assert_equal('bar1', I18n.t(:bar1))
assert_equal('bar2', I18n.t(:bar2))
end
end
end
3 changes: 2 additions & 1 deletion test/test_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,14 @@
::ActiveRecord::Migration.verbose = false
::ActiveRecord::Schema.define(version: 1) do
create_table :translations, force: true do |t|
t.string :scope
t.string :locale
t.string :key
t.text :value
t.text :interpolations
t.boolean :is_proc, default: false
end
add_index :translations, %i[locale key], unique: true
add_index :translations, %i[scope locale key], unique: true
end
end

Expand Down

0 comments on commit 7bae168

Please sign in to comment.