i18n-active_record 1.1.0 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 934e01acf036e3a1c8eb23f5f8f96c55e84d462a31a10183c12389e8466e233d
4
- data.tar.gz: a0c8301e9e0c5eaac6badf2dfdeca19b581296eaa0e0a15464a13fbc6796087f
3
+ metadata.gz: a0bb9a3f4087d304d5ee5fdc38b8df8e31147a412c618fed9c82f1363db579be
4
+ data.tar.gz: b77a32f97c5d1785084a5c8332ff7e8909ce81ec6d3724ec664650540c72451d
5
5
  SHA512:
6
- metadata.gz: 0702e26d0b3a600ff2d28db7473e9a34311f18a099a0009ec6bccec5382d5c4bcc9042b33653a214c377c332db0d902adb64103e05a98c1371d6d19ccb3c0297
7
- data.tar.gz: f2dd449433f4b88763c5952831feff25956c727aa4ff086c2ae130709bfd968ef36f61bf7b2af9065681ac7132e7e7c3a05c13b268e5c1c3e282285cd1787c6b
6
+ metadata.gz: 46eb68288d4b64db1760235e72fd73a3a03e7e06d19b9f699ed4b160a423dfde3333fe92f9556fd65ed2d3f1e5d8e1e14d5ffebcfa7d7251fd37632bc3b36f44
7
+ data.tar.gz: 7f1ace5489592b78a2e0dab66564837025a21cb0a2b10dbaf3999a4ea128c0c983ba8f952b867236d71554226553b2c119ad32a232cf3a96c29f62200b29b9c9
data/README.md CHANGED
@@ -89,11 +89,26 @@ end
89
89
 
90
90
  You can now use `I18n.t('Your String')` to lookup translations in the database.
91
91
 
92
- ## Missing Translations
92
+ ## Custom translation model
93
+
94
+ By default, the gem relies on [the built-in translation model](https://github.com/svenfuchs/i18n-active_record/blob/master/lib/i18n/backend/active_record/translation.rb).
95
+ However, to extend the default functionality, the translation model can be customized:
96
+
97
+ ```ruby
98
+ class MyTranslation < I18n::Backend::ActiveRecord::Translation
99
+ def value=(val)
100
+ super("custom #{val}")
101
+ end
102
+ end
93
103
 
94
- ### Usage
104
+ I18n::Backend::ActiveRecord.configure do |config|
105
+ config.translation_model = MyTranslation
106
+ end
107
+ ```
108
+
109
+ ## Missing Translations
95
110
 
96
- In order to make the `I18n::Backend::ActiveRecord::Missing` module working correctly pluralization rules should be configured properly.
111
+ To make the `I18n::Backend::ActiveRecord::Missing` module working correctly pluralization rules should be configured properly.
97
112
  The `i18n.plural.keys` translation key should be present in any of the backends.
98
113
  See https://github.com/svenfuchs/i18n-active_record/blob/master/lib/i18n/backend/active_record/missing.rb for more information.
99
114
 
@@ -115,7 +130,7 @@ The `interpolations` field is otherwise unused since the "value" in `Translation
115
130
 
116
131
  ## Examples
117
132
 
118
- * http://collectiveidea.com/blog/archives/2016/05/31/beyond-yml-files-dynamic-translations/
133
+ * http://collectiveidea.com/blog/archives/2016/05/31/beyond-yml-files-dynamic-translations/ ([use `before_action`](https://github.com/svenfuchs/i18n-active_record/issues/138) for Rails 5.1+)
119
134
 
120
135
  ## Contributing
121
136
 
@@ -2,6 +2,6 @@
2
2
 
3
3
  module I18n
4
4
  module ActiveRecord
5
- VERSION = '1.1.0'
5
+ VERSION = '1.3.0'
6
6
  end
7
7
  end
@@ -4,11 +4,12 @@ module I18n
4
4
  module Backend
5
5
  class ActiveRecord
6
6
  class Configuration
7
- attr_accessor :cleanup_with_destroy, :cache_translations
7
+ attr_accessor :cleanup_with_destroy, :cache_translations, :translation_model
8
8
 
9
9
  def initialize
10
10
  @cleanup_with_destroy = false
11
11
  @cache_translations = false
12
+ @translation_model = I18n::Backend::ActiveRecord::Translation
12
13
  end
13
14
  end
14
15
  end
@@ -36,13 +36,14 @@ module I18n
36
36
  class ActiveRecord
37
37
  module Missing
38
38
  include Flatten
39
+ include TranslationModel
39
40
 
40
41
  def store_default_translations(locale, key, options = {})
41
42
  count, scope, _, separator = options.values_at(:count, :scope, :default, :separator)
42
43
  separator ||= I18n.default_separator
43
44
  key = normalize_flat_keys(locale, key, scope, separator)
44
45
 
45
- return if ActiveRecord::Translation.locale(locale).lookup(key).exists?
46
+ return if translation_model.locale(locale).lookup(key).exists?
46
47
 
47
48
  interpolations = options.keys - I18n::RESERVED_KEYS
48
49
  keys = count ? I18n.t('i18n.plural.keys', locale: locale).map { |k| [key, k].join(FLATTEN_SEPARATOR) } : [key]
@@ -50,7 +51,7 @@ module I18n
50
51
  end
51
52
 
52
53
  def store_default_translation(locale, key, interpolations)
53
- translation = ActiveRecord::Translation.new locale: locale.to_s, key: key
54
+ translation = translation_model.new locale: locale.to_s, key: key
54
55
  translation.interpolations = interpolations
55
56
  translation.save
56
57
  end
@@ -23,6 +23,8 @@ module I18n
23
23
  module Backend
24
24
  class ActiveRecord
25
25
  module StoreProcs
26
+ extend TranslationModel
27
+
26
28
  def value=(val)
27
29
  case val
28
30
  when Proc
@@ -33,7 +35,7 @@ module I18n
33
35
  end
34
36
  end
35
37
 
36
- Translation.send(:include, self) if method(:to_s).respond_to?(:to_ruby)
38
+ translation_model.send(:include, self) if method(:to_s).respond_to?(:to_ruby)
37
39
  end
38
40
  end
39
41
  end
@@ -53,8 +53,14 @@ module I18n
53
53
 
54
54
  self.table_name = 'translations'
55
55
 
56
- serialize :value
57
- serialize :interpolations, Array
56
+ if ::ActiveRecord.version >= Gem::Version.new('7.1.0.alpha')
57
+ serialize :value, coder: YAML
58
+ serialize :interpolations, coder: YAML, type: Array
59
+ else
60
+ serialize :value
61
+ serialize :interpolations, Array
62
+ end
63
+
58
64
  after_commit :invalidate_translations_cache
59
65
 
60
66
  class << self
@@ -79,7 +85,7 @@ module I18n
79
85
  Translation.select('DISTINCT locale').to_a.map { |t| t.locale.to_sym }
80
86
  end
81
87
 
82
- def to_hash
88
+ def to_h
83
89
  Translation.all.each.with_object({}) do |t, memo|
84
90
  locale_hash = (memo[t.locale.to_sym] ||= {})
85
91
  keys = t.key.split('.')
@@ -25,12 +25,21 @@ module I18n
25
25
  reload!
26
26
  end
27
27
 
28
+ module TranslationModel
29
+ private
30
+
31
+ def translation_model
32
+ I18n::Backend::ActiveRecord.config.translation_model
33
+ end
34
+ end
35
+
28
36
  module Implementation
29
37
  include Base
30
38
  include Flatten
39
+ include TranslationModel
31
40
 
32
41
  def available_locales
33
- Translation.available_locales
42
+ translation_model.available_locales
34
43
  rescue ::ActiveRecord::StatementInvalid
35
44
  []
36
45
  end
@@ -39,7 +48,7 @@ module I18n
39
48
  escape = options.fetch(:escape, true)
40
49
 
41
50
  flatten_translations(locale, data, escape, false).each do |key, value|
42
- translation = Translation.locale(locale).lookup(expand_keys(key))
51
+ translation = translation_model.locale(locale).lookup(expand_keys(key))
43
52
 
44
53
  if self.class.config.cleanup_with_destroy
45
54
  translation.destroy_all
@@ -47,7 +56,7 @@ module I18n
47
56
  translation.delete_all
48
57
  end
49
58
 
50
- Translation.create(locale: locale.to_s, key: key.to_s, value: value)
59
+ translation_model.create(locale: locale.to_s, key: key.to_s, value: value)
51
60
  end
52
61
 
53
62
  reload! if self.class.config.cache_translations
@@ -64,7 +73,7 @@ module I18n
64
73
  end
65
74
 
66
75
  def init_translations
67
- @translations = Translation.to_hash
76
+ @translations = translation_model.to_h
68
77
  end
69
78
 
70
79
  def translations(do_init: false)
@@ -86,9 +95,9 @@ module I18n
86
95
  end
87
96
 
88
97
  result = if key == ''
89
- Translation.locale(locale).all
98
+ translation_model.locale(locale).all
90
99
  else
91
- Translation.locale(locale).lookup(key)
100
+ translation_model.locale(locale).lookup(key)
92
101
  end
93
102
 
94
103
  if result.empty?
@@ -123,7 +123,7 @@ class I18nBackendActiveRecordTest < I18n::TestCase
123
123
  I18n.t('.') # Fixes test flakiness by loading available locales
124
124
  I18n::Backend::ActiveRecord::Translation.destroy_all
125
125
 
126
- assert_equal 'translation missing: en.no key', I18n.t('.')
126
+ assert_match(/[Tt]ranslation missing: en\.no key/, I18n.t('.'))
127
127
  end
128
128
 
129
129
  test 'intially unitinitialized' do
@@ -172,4 +172,23 @@ class I18nBackendActiveRecordTest < I18n::TestCase
172
172
  I18n.t('foo')
173
173
  end
174
174
  end
175
+
176
+ class WithCustomTranslationModel < I18nBackendActiveRecordTest
177
+ class CustomTranslation < I18n::Backend::ActiveRecord::Translation
178
+ def value=(val)
179
+ super("custom #{val}")
180
+ end
181
+ end
182
+
183
+ def setup
184
+ super
185
+
186
+ I18n::Backend::ActiveRecord.config.translation_model = CustomTranslation
187
+ end
188
+
189
+ test 'use a custom model' do
190
+ store_translations(:en, foo: 'foo')
191
+ assert_equal I18n.t(:foo), 'custom foo'
192
+ end
193
+ end
175
194
  end
data/test/test_helper.rb CHANGED
@@ -10,35 +10,35 @@ require 'i18n/tests'
10
10
 
11
11
  begin
12
12
  require 'active_record'
13
- ::ActiveRecord::Base.connection
13
+ ActiveRecord::Base.connection
14
14
  rescue LoadError => e
15
15
  puts "can't use ActiveRecord backend because: #{e.message}"
16
- rescue ::ActiveRecord::ConnectionNotEstablished
16
+ rescue ActiveRecord::ConnectionNotEstablished
17
17
  require 'i18n/backend/active_record'
18
18
 
19
- case ENV['DB']
19
+ case ENV.fetch('DB', nil)
20
20
  when 'postgres'
21
- ::ActiveRecord::Base.establish_connection(
21
+ ActiveRecord::Base.establish_connection(
22
22
  adapter: 'postgresql',
23
23
  database: 'i18n_unittest',
24
- username: ENV['PG_USER'] || 'postgres',
25
- password: ENV['PG_PASSWORD'] || 'postgres',
24
+ username: ENV.fetch('PG_USER', 'postgres'),
25
+ password: ENV.fetch('PG_PASSWORD', 'postgres'),
26
26
  host: 'localhost'
27
27
  )
28
28
  when 'mysql'
29
- ::ActiveRecord::Base.establish_connection(
29
+ ActiveRecord::Base.establish_connection(
30
30
  adapter: 'mysql2',
31
31
  database: 'i18n_unittest',
32
- username: ENV['MYSQL_USER'] || 'root',
33
- password: ENV['MYSQL_PASSWORD'] || '',
32
+ username: ENV.fetch('MYSQL_USER', 'root'),
33
+ password: ENV.fetch('MYSQL_PASSWORD', ''),
34
34
  host: '127.0.0.1'
35
35
  )
36
36
  else
37
- ::ActiveRecord::Base.establish_connection adapter: 'sqlite3', database: ':memory:'
37
+ ActiveRecord::Base.establish_connection adapter: 'sqlite3', database: ':memory:'
38
38
  end
39
39
 
40
- ::ActiveRecord::Migration.verbose = false
41
- ::ActiveRecord::Schema.define(version: 1) do
40
+ ActiveRecord::Migration.verbose = false
41
+ ActiveRecord::Schema.define(version: 1) do
42
42
  create_table :translations, force: true do |t|
43
43
  t.string :locale
44
44
  t.string :key
@@ -48,6 +48,12 @@ rescue ::ActiveRecord::ConnectionNotEstablished
48
48
  end
49
49
  add_index :translations, %i[locale key], unique: true
50
50
  end
51
+
52
+ if ActiveRecord::Base.respond_to?(:yaml_column_permitted_classes=)
53
+ ActiveRecord::Base.yaml_column_permitted_classes = [Symbol]
54
+ elsif ActiveRecord.respond_to?(:yaml_column_permitted_classes=)
55
+ ActiveRecord.yaml_column_permitted_classes = [Symbol]
56
+ end
51
57
  end
52
58
 
53
59
  TEST_CASE = defined?(Minitest::Test) ? Minitest::Test : MiniTest::Unit::TestCase
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.1.0
4
+ version: 1.3.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: 2021-12-01 00:00:00.000000000 Z
11
+ date: 2023-09-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: i18n
@@ -150,7 +150,8 @@ files:
150
150
  homepage: http://github.com/svenfuchs/i18n-active_record
151
151
  licenses:
152
152
  - MIT
153
- metadata: {}
153
+ metadata:
154
+ rubygems_mfa_required: 'true'
154
155
  post_install_message:
155
156
  rdoc_options: []
156
157
  require_paths:
@@ -166,7 +167,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
166
167
  - !ruby/object:Gem::Version
167
168
  version: '0'
168
169
  requirements: []
169
- rubygems_version: 3.2.29
170
+ rubygems_version: 3.4.10
170
171
  signing_key:
171
172
  specification_version: 4
172
173
  summary: I18n ActiveRecord backend