i18n-active_record 1.3.0 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a0bb9a3f4087d304d5ee5fdc38b8df8e31147a412c618fed9c82f1363db579be
4
- data.tar.gz: b77a32f97c5d1785084a5c8332ff7e8909ce81ec6d3724ec664650540c72451d
3
+ metadata.gz: a6895e3f4b2c615221ac6a44bba495f6a6557e76fe5815fe604005e3e9d455d0
4
+ data.tar.gz: febd2054212ebeec7624de340aebc0c9f86ae4ec509f55751f97459adef82bf9
5
5
  SHA512:
6
- metadata.gz: 46eb68288d4b64db1760235e72fd73a3a03e7e06d19b9f699ed4b160a423dfde3333fe92f9556fd65ed2d3f1e5d8e1e14d5ffebcfa7d7251fd37632bc3b36f44
7
- data.tar.gz: 7f1ace5489592b78a2e0dab66564837025a21cb0a2b10dbaf3999a4ea128c0c983ba8f952b867236d71554226553b2c119ad32a232cf3a96c29f62200b29b9c9
6
+ metadata.gz: 3fbd83d43d6158a23eb0573a598c87c23986912403496761d60b9e72950d06ff0897e6e911bb2f3d1073ab0066e17d7aa02c0f288e6b2f43bacad3f306f31625
7
+ data.tar.gz: b51858da9da92d578fe190a185e45df9779e34dfb07c5b8daf097059edf18394c83fbbb1f2add6ac72b59e8ff19342f1ba3190bb72bee322a4430e25decce5ae
data/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  # I18n::Backend::ActiveRecord [![Ruby Style Guide](https://img.shields.io/badge/code_style-rubocop-brightgreen.svg)](https://github.com/rubocop/rubocop) [![Tests Status](https://github.com/svenfuchs/i18n-active_record/actions/workflows/test.yml/badge.svg)](https://github.com/svenfuchs/i18n-active_record/actions) [![Linter Status](https://github.com/svenfuchs/i18n-active_record/actions/workflows/linter.yml/badge.svg)](https://github.com/svenfuchs/i18n-active_record/actions)
2
2
 
3
3
  This repository contains the I18n ActiveRecord backend and support code that has been extracted from the `I18n` gem: http://github.com/svenfuchs/i18n.
4
- It is fully compatible with Rails 4, 5 and 6.
4
+ It is fully compatible with Rails 4+.
5
5
 
6
6
  ## Installation
7
7
 
@@ -85,6 +85,16 @@ I18n::Backend::ActiveRecord.configure do |config|
85
85
  end
86
86
  ```
87
87
 
88
+ The ActiveRecord backend can be configured to use a `scope` to isolate sets of translations. That way, two applications
89
+ using the backend with the same database table can use translation data independently of one another.
90
+ If configured with a scope, all data used will be limited to records with that particular scope identifier:
91
+
92
+ ```ruby
93
+ I18n::Backend::ActiveRecord.configure do |config|
94
+ config.scope = 'app1' # defaults to nil, disabling scope
95
+ end
96
+ ```
97
+
88
98
  ## Usage
89
99
 
90
100
  You can now use `I18n.t('Your String')` to lookup translations in the database.
@@ -15,4 +15,5 @@ end
15
15
  I18n::Backend::ActiveRecord.configure do |config|
16
16
  # config.cache_translations = true # defaults to false
17
17
  # config.cleanup_with_destroy = true # defaults to false
18
+ # config.scope = 'app_scope' # defaults to nil, won't be used
18
19
  end
@@ -1,6 +1,7 @@
1
1
  class <%= migration_class_name %> < ActiveRecord::Migration[<%= ActiveRecord::Migration.current_version %>]
2
2
  def change
3
3
  create_table :<%= table_name %> do |t|
4
+ t.string :scope
4
5
  t.string :locale
5
6
  t.string :key
6
7
  t.text :value
@@ -4,4 +4,5 @@ I18n.backend = I18n::Backend::ActiveRecord.new
4
4
  I18n::Backend::ActiveRecord.configure do |config|
5
5
  # config.cache_translations = true # defaults to false
6
6
  # config.cleanup_with_destroy = true # defaults to false
7
+ # config.scope = 'app_scope' # defaults to nil, won't be used
7
8
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module I18n
4
4
  module ActiveRecord
5
- VERSION = '1.3.0'
5
+ VERSION = '1.4.0'
6
6
  end
7
7
  end
@@ -4,12 +4,13 @@ module I18n
4
4
  module Backend
5
5
  class ActiveRecord
6
6
  class Configuration
7
- attr_accessor :cleanup_with_destroy, :cache_translations, :translation_model
7
+ attr_accessor :cleanup_with_destroy, :cache_translations, :translation_model, :scope
8
8
 
9
9
  def initialize
10
10
  @cleanup_with_destroy = false
11
11
  @cache_translations = false
12
12
  @translation_model = I18n::Backend::ActiveRecord::Translation
13
+ @scope = nil
13
14
  end
14
15
  end
15
16
  end
@@ -61,13 +61,24 @@ module I18n
61
61
  serialize :interpolations, Array
62
62
  end
63
63
 
64
+ before_validation :set_scope
64
65
  after_commit :invalidate_translations_cache
65
66
 
67
+ default_scope { scoped }
68
+
66
69
  class << self
67
70
  def locale(locale)
68
71
  where(locale: locale.to_s)
69
72
  end
70
73
 
74
+ def scoped
75
+ if (record_scope = ActiveRecord.config.scope)
76
+ where(scope: record_scope)
77
+ else
78
+ all
79
+ end
80
+ end
81
+
71
82
  def lookup(keys, *separator)
72
83
  column_name = connection.quote_column_name('key')
73
84
  keys = Array(keys).map!(&:to_s)
@@ -82,11 +93,11 @@ module I18n
82
93
  end
83
94
 
84
95
  def available_locales
85
- Translation.select('DISTINCT locale').to_a.map { |t| t.locale.to_sym }
96
+ select('DISTINCT locale').to_a.map { |t| t.locale.to_sym }
86
97
  end
87
98
 
88
99
  def to_h
89
- Translation.all.each.with_object({}) do |t, memo|
100
+ all.each.with_object({}) do |t, memo|
90
101
  locale_hash = (memo[t.locale.to_sym] ||= {})
91
102
  keys = t.key.split('.')
92
103
  keys.each.with_index.inject(locale_hash) do |iterator, (key_part, index)|
@@ -129,6 +140,12 @@ module I18n
129
140
  def invalidate_translations_cache
130
141
  I18n.backend.reload! if I18n::Backend::ActiveRecord.config.cache_translations
131
142
  end
143
+
144
+ private
145
+
146
+ def set_scope
147
+ self.scope ||= ActiveRecord.config.scope if ActiveRecord.config.scope
148
+ end
132
149
  end
133
150
  end
134
151
  end
@@ -191,4 +191,35 @@ class I18nBackendActiveRecordTest < I18n::TestCase
191
191
  assert_equal I18n.t(:foo), 'custom foo'
192
192
  end
193
193
  end
194
+
195
+ class ScopeTest < I18nBackendActiveRecordTest
196
+ def setup
197
+ super
198
+
199
+ I18n::Backend::ActiveRecord.config.scope = 'scope1'
200
+ end
201
+
202
+ test 'scope config option divides translations into isolated sets' do
203
+ store_translations(:en, foo: 'foo1')
204
+ assert_equal('foo1', I18n.t(:foo))
205
+
206
+ I18n::Backend::ActiveRecord.config.scope = 'scope2'
207
+ store_translations(:en, foo: 'foo2')
208
+ assert_equal('foo2', I18n.t(:foo))
209
+
210
+ I18n::Backend::ActiveRecord.config.scope = 'scope1'
211
+ assert_equal('foo1', I18n.t(:foo))
212
+ end
213
+
214
+ test 'scope config of nil disables scope' do
215
+ store_translations(:en, bar1: 'bar1')
216
+
217
+ I18n::Backend::ActiveRecord.config.scope = 'scope2'
218
+ store_translations(:en, bar2: 'bar2')
219
+
220
+ I18n::Backend::ActiveRecord.config.scope = nil
221
+ assert_equal('bar1', I18n.t(:bar1))
222
+ assert_equal('bar2', I18n.t(:bar2))
223
+ end
224
+ end
194
225
  end
data/test/test_helper.rb CHANGED
@@ -40,13 +40,14 @@ rescue ActiveRecord::ConnectionNotEstablished
40
40
  ActiveRecord::Migration.verbose = false
41
41
  ActiveRecord::Schema.define(version: 1) do
42
42
  create_table :translations, force: true do |t|
43
+ t.string :scope
43
44
  t.string :locale
44
45
  t.string :key
45
46
  t.text :value
46
47
  t.text :interpolations
47
48
  t.boolean :is_proc, default: false
48
49
  end
49
- add_index :translations, %i[locale key], unique: true
50
+ add_index :translations, %i[scope locale key], unique: true
50
51
  end
51
52
 
52
53
  if ActiveRecord::Base.respond_to?(:yaml_column_permitted_classes=)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: i18n-active_record
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.0
4
+ version: 1.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sven Fuchs
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-09-18 00:00:00.000000000 Z
11
+ date: 2024-12-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: i18n