mobility 0.8.13 → 1.0.0.alpha

Sign up to get free protection for your applications and to get access to all the features.
Files changed (93) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/CHANGELOG.md +26 -0
  5. data/Gemfile +5 -2
  6. data/Gemfile.lock +79 -8
  7. data/README.md +183 -91
  8. data/lib/mobility.rb +40 -166
  9. data/lib/mobility/arel/nodes/pg_ops.rb +1 -1
  10. data/lib/mobility/backend.rb +19 -41
  11. data/lib/mobility/backends.rb +20 -0
  12. data/lib/mobility/backends/active_record.rb +4 -0
  13. data/lib/mobility/backends/active_record/column.rb +2 -0
  14. data/lib/mobility/backends/active_record/container.rb +4 -2
  15. data/lib/mobility/backends/active_record/hstore.rb +2 -0
  16. data/lib/mobility/backends/active_record/json.rb +2 -0
  17. data/lib/mobility/backends/active_record/jsonb.rb +2 -0
  18. data/lib/mobility/backends/active_record/key_value.rb +5 -3
  19. data/lib/mobility/backends/active_record/pg_hash.rb +1 -1
  20. data/lib/mobility/backends/active_record/serialized.rb +2 -0
  21. data/lib/mobility/backends/active_record/table.rb +5 -3
  22. data/lib/mobility/backends/column.rb +0 -6
  23. data/lib/mobility/backends/container.rb +2 -1
  24. data/lib/mobility/backends/hash.rb +39 -0
  25. data/lib/mobility/backends/hstore.rb +0 -1
  26. data/lib/mobility/backends/json.rb +0 -1
  27. data/lib/mobility/backends/jsonb.rb +0 -1
  28. data/lib/mobility/backends/key_value.rb +22 -14
  29. data/lib/mobility/backends/null.rb +2 -0
  30. data/lib/mobility/backends/sequel.rb +3 -0
  31. data/lib/mobility/backends/sequel/column.rb +2 -0
  32. data/lib/mobility/backends/sequel/container.rb +3 -1
  33. data/lib/mobility/backends/sequel/hstore.rb +2 -0
  34. data/lib/mobility/backends/sequel/json.rb +2 -0
  35. data/lib/mobility/backends/sequel/jsonb.rb +3 -1
  36. data/lib/mobility/backends/sequel/key_value.rb +8 -6
  37. data/lib/mobility/backends/sequel/serialized.rb +2 -0
  38. data/lib/mobility/backends/sequel/table.rb +5 -2
  39. data/lib/mobility/backends/serialized.rb +1 -3
  40. data/lib/mobility/backends/table.rb +14 -6
  41. data/lib/mobility/pluggable.rb +36 -0
  42. data/lib/mobility/plugin.rb +260 -0
  43. data/lib/mobility/plugins.rb +26 -25
  44. data/lib/mobility/plugins/active_model.rb +17 -0
  45. data/lib/mobility/plugins/active_model/cache.rb +26 -0
  46. data/lib/mobility/plugins/active_model/dirty.rb +112 -77
  47. data/lib/mobility/plugins/active_record.rb +34 -0
  48. data/lib/mobility/plugins/active_record/backend.rb +25 -0
  49. data/lib/mobility/plugins/active_record/cache.rb +28 -0
  50. data/lib/mobility/plugins/active_record/dirty.rb +34 -17
  51. data/lib/mobility/plugins/active_record/query.rb +43 -31
  52. data/lib/mobility/plugins/active_record/uniqueness_validation.rb +60 -0
  53. data/lib/mobility/plugins/attribute_methods.rb +28 -20
  54. data/lib/mobility/plugins/attributes.rb +70 -0
  55. data/lib/mobility/plugins/backend.rb +138 -0
  56. data/lib/mobility/plugins/backend_reader.rb +34 -0
  57. data/lib/mobility/plugins/cache.rb +59 -24
  58. data/lib/mobility/plugins/default.rb +22 -17
  59. data/lib/mobility/plugins/dirty.rb +12 -33
  60. data/lib/mobility/plugins/fallbacks.rb +51 -43
  61. data/lib/mobility/plugins/fallthrough_accessors.rb +20 -23
  62. data/lib/mobility/plugins/locale_accessors.rb +25 -35
  63. data/lib/mobility/plugins/presence.rb +28 -21
  64. data/lib/mobility/plugins/query.rb +8 -17
  65. data/lib/mobility/plugins/reader.rb +50 -0
  66. data/lib/mobility/plugins/sequel.rb +34 -0
  67. data/lib/mobility/plugins/sequel/backend.rb +25 -0
  68. data/lib/mobility/plugins/sequel/cache.rb +24 -0
  69. data/lib/mobility/plugins/sequel/dirty.rb +32 -21
  70. data/lib/mobility/plugins/sequel/query.rb +21 -6
  71. data/lib/mobility/plugins/writer.rb +44 -0
  72. data/lib/mobility/translations.rb +95 -0
  73. data/lib/mobility/version.rb +12 -1
  74. data/lib/rails/generators/mobility/templates/initializer.rb +95 -77
  75. metadata +28 -27
  76. metadata.gz.sig +0 -0
  77. data/lib/mobility/active_model.rb +0 -4
  78. data/lib/mobility/active_model/backend_resetter.rb +0 -26
  79. data/lib/mobility/active_record.rb +0 -23
  80. data/lib/mobility/active_record/backend_resetter.rb +0 -26
  81. data/lib/mobility/active_record/uniqueness_validator.rb +0 -60
  82. data/lib/mobility/attributes.rb +0 -324
  83. data/lib/mobility/backend/orm_delegator.rb +0 -44
  84. data/lib/mobility/backend_resetter.rb +0 -50
  85. data/lib/mobility/configuration.rb +0 -138
  86. data/lib/mobility/fallbacks.rb +0 -28
  87. data/lib/mobility/interface.rb +0 -0
  88. data/lib/mobility/loaded.rb +0 -4
  89. data/lib/mobility/plugins/active_record/attribute_methods.rb +0 -38
  90. data/lib/mobility/plugins/cache/translation_cacher.rb +0 -40
  91. data/lib/mobility/sequel.rb +0 -9
  92. data/lib/mobility/sequel/backend_resetter.rb +0 -23
  93. data/lib/mobility/translates.rb +0 -73
@@ -1,324 +0,0 @@
1
- # frozen_string_literal: true
2
- require "mobility/util"
3
-
4
- module Mobility
5
- =begin
6
-
7
- Defines accessor methods to include on model class. Inspired by Traco's
8
- +Traco::Attributes+ class.
9
-
10
- Normally this class will be created through class methods defined using
11
- {Mobility::Translates} accessor methods, and need not be created directly.
12
- However, the class is central to how Mobility hooks into models to add
13
- accessors and other methods, and should be useful as a reference when
14
- understanding and designing backends.
15
-
16
- ==Including Attributes in a Class
17
-
18
- Since {Attributes} is a subclass of +Module+, including an instance of it is
19
- like including a module. Creating an instance like this:
20
-
21
- Attributes.new("title", backend: :my_backend, locale_accessors: [:en, :ja], cache: true, fallbacks: true)
22
-
23
- will generate an anonymous module that behaves approximately like this:
24
-
25
- Module.new do
26
- def mobility_backends
27
- # Returns a memoized hash with attribute name keys and backend instance
28
- # values. When a key is fetched from the hash, the hash calls
29
- # +self.class.mobility_backend_class(name)+ (where +name+ is the
30
- # attribute name) to get the backend class, then instantiate it (passing
31
- # the model instance and attribute name to its initializer) and return it.
32
- #
33
- # The backend class returned from the class method
34
- # +mobility_backend_class+ returns a subclass of
35
- # +Mobility::Backends::MyBackend+ and includes into it:
36
- #
37
- # - Mobility::Plugins::Cache (from the +cache: true+ option)
38
- # - instance of Mobility::Plugins::Fallbacks (from the +fallbacks: true+ option)
39
- # - Mobility::Plugins::Presence (by default, disabled by +presence: false+)
40
- end
41
-
42
- def title(locale: Mobility.locale)
43
- mobility_backends[:title].read(locale)
44
- end
45
-
46
- def title?(locale: Mobility.locale)
47
- mobility_backends[:title].read(locale).present?
48
- end
49
-
50
- def title=(value, locale: Mobility.locale)
51
- mobility_backends[:title].write(locale, value)
52
- end
53
-
54
- # Start Locale Accessors
55
- #
56
- def title_en
57
- title(locale: :en)
58
- end
59
-
60
- def title_en?
61
- title?(locale: :en)
62
- end
63
-
64
- def title_en=(value)
65
- public_send(:title=, value, locale: :en)
66
- end
67
-
68
- def title_ja
69
- title(locale: :ja)
70
- end
71
-
72
- def title_ja?
73
- title?(locale: :ja)
74
- end
75
-
76
- def title_ja=(value)
77
- public_send(:title=, value, locale: :ja)
78
- end
79
- # End Locale Accessors
80
- end
81
-
82
- Including this module into a model class will thus add the backend method, the
83
- reader, writer and presence methods, and the locale accessor so the model
84
- class. (These methods are in fact added to the model in an +included+ hook.)
85
-
86
- Note that some simplifications have been made above for readability. (In
87
- reality, all getters and setters accept an options hash which is passed along
88
- to the backend instance.)
89
-
90
- ==Setting up the Model Class
91
-
92
- Accessor methods alone are of limited use without a hook to actually modify the
93
- model class. This hook is provided by the {Backend::Setup#setup_model} method,
94
- which is added to every backend class when it includes the {Backend} module.
95
-
96
- Assuming the backend has defined a setup block by calling +setup+, this block
97
- will be called when {Attributes} is {#included} in the model class, passed
98
- attributes and options defined when the backend was defined on the model class.
99
- This allows a backend to do things like (for example) define associations on a
100
- model class required by the backend, as happens in the {Backends::KeyValue} and
101
- {Backends::Table} backends.
102
-
103
- Since setup blocks are evaluated on the model class, it is possible that
104
- backends can conflict (for example, overwriting previously defined methods).
105
- Care should be taken to avoid defining methods on the model class, or where
106
- necessary, ensure that names are defined in such a way as to avoid conflicts
107
- with other backends.
108
-
109
- =end
110
- class Attributes < Module
111
-
112
- # Method (accessor, reader or writer)
113
- # @return [Symbol] method
114
- attr_reader :method
115
-
116
- # Attribute names for which accessors will be defined
117
- # @return [Array<String>] Array of names
118
- attr_reader :names
119
-
120
- # Backend options
121
- # @return [Hash] Backend options
122
- attr_reader :options
123
-
124
- # Backend class
125
- # @return [Class] Backend class
126
- attr_reader :backend_class
127
-
128
- # Name of backend
129
- # @return [Symbol,Class] Name of backend, or backend class
130
- attr_reader :backend_name
131
-
132
- # Model class
133
- # @return [Class] Class of model
134
- attr_reader :model_class
135
-
136
- # @param [Symbol] method One of: [reader, writer, accessor]
137
- # @param [Array<String>] attribute_names Names of attributes to define backend for
138
- # @param [Hash] backend_options Backend options hash
139
- # @option backend_options [Class] model_class Class of model
140
- # @raise [ArgumentError] if method is not reader, writer or accessor
141
- def initialize(*attribute_names, method: :accessor, backend: Mobility.default_backend, **backend_options)
142
- raise ArgumentError, "method must be one of: reader, writer, accessor" unless %i[reader writer accessor].include?(method)
143
- @method = method
144
- @options = Mobility.default_options.to_h.merge(backend_options)
145
- @names = attribute_names.map(&:to_s).freeze
146
- raise BackendRequired, "Backend option required if Mobility.config.default_backend is not set." if backend.nil?
147
- @backend_name = backend
148
- end
149
-
150
- # Setup backend class, include modules into model class, include/extend
151
- # shared modules and setup model with backend setup block (see
152
- # {Mobility::Backend::Setup#setup_model}).
153
- # @param klass [Class] Class of model
154
- def included(klass)
155
- @model_class = @options[:model_class] = klass
156
- @backend_class = get_backend_class(backend_name).for(model_class).with_options(options)
157
-
158
- Mobility.plugins.each do |name|
159
- plugin = get_plugin_class(name)
160
- plugin.apply(self, options[name])
161
- end
162
-
163
- each do |name|
164
- define_backend(name)
165
- define_reader(name) if %i[accessor reader].include?(method)
166
- define_writer(name) if %i[accessor writer].include?(method)
167
- end
168
-
169
- klass.include InstanceMethods
170
- klass.extend ClassMethods
171
-
172
- backend_class.setup_model(model_class, names)
173
- end
174
-
175
- # Yield each attribute name to block
176
- # @yieldparam [String] Attribute
177
- def each &block
178
- names.each(&block)
179
- end
180
-
181
- # Show useful information about this module.
182
- # @return [String]
183
- def inspect
184
- "#<Attributes (#{backend_name}) @names=#{names.join(", ")}>"
185
- end
186
-
187
- private
188
-
189
- def define_backend(attribute)
190
- module_eval <<-EOM, __FILE__, __LINE__ + 1
191
- def #{Backend.method_name(attribute)}
192
- mobility_backends[:#{attribute}]
193
- end
194
- EOM
195
- end
196
-
197
- def define_reader(attribute)
198
- class_eval <<-EOM, __FILE__, __LINE__ + 1
199
- def #{attribute}(**options)
200
- return super() if options.delete(:super)
201
- #{set_locale_from_options_inline}
202
- mobility_backends[:#{attribute}].read(locale, options)
203
- end
204
-
205
- def #{attribute}?(**options)
206
- return super() if options.delete(:super)
207
- #{set_locale_from_options_inline}
208
- mobility_backends[:#{attribute}].present?(locale, options)
209
- end
210
- EOM
211
- end
212
-
213
- def define_writer(attribute)
214
- class_eval <<-EOM, __FILE__, __LINE__ + 1
215
- def #{attribute}=(value, **options)
216
- return super(value) if options.delete(:super)
217
- #{set_locale_from_options_inline}
218
- mobility_backends[:#{attribute}].write(locale, value, options)
219
- end
220
- EOM
221
- end
222
-
223
- # This string is evaluated inline in order to optimize performance of
224
- # getters and setters, avoiding extra steps where they are unneeded.
225
- def set_locale_from_options_inline
226
- <<-EOL
227
- if options[:locale]
228
- #{"Mobility.enforce_available_locales!(options[:locale])" if I18n.enforce_available_locales}
229
- locale = options[:locale].to_sym
230
- options[:locale] &&= !!locale
231
- else
232
- locale = Mobility.locale
233
- end
234
- EOL
235
- end
236
-
237
- def get_backend_class(backend)
238
- return backend if Module === backend
239
- require "mobility/backends/#{backend}"
240
- get_class_from_key(Mobility::Backends, backend)
241
- end
242
-
243
- def get_plugin_class(plugin)
244
- require "mobility/plugins/#{plugin}"
245
- get_class_from_key(Mobility::Plugins, plugin)
246
- end
247
-
248
- def get_class_from_key(parent_class, key)
249
- klass_name = key.to_s.gsub(/(^|_)(.)/){|x| x[-1..-1].upcase}
250
- parent_class.const_get(klass_name)
251
- end
252
-
253
- module InstanceMethods
254
- # Return a new backend for an attribute name.
255
- # @return [Hash] Hash of attribute names and backend instances
256
- # @api private
257
- def mobility_backends
258
- @mobility_backends ||= Hash.new do |hash, name|
259
- next hash[name.to_sym] if String === name
260
- hash[name] = self.class.mobility_backend_class(name).new(self, name.to_s)
261
- end
262
- end
263
-
264
- def initialize_dup(other)
265
- @mobility_backends = nil
266
- super
267
- end
268
- end
269
-
270
- module ClassMethods
271
- # Return all {Mobility::Attribute} module instances from among ancestors
272
- # of this model.
273
- # @return [Array<Mobility::Attributes>] Attribute modules
274
- def mobility_modules
275
- ancestors.grep(Attributes)
276
- end
277
-
278
- # Return translated attribute names on this model.
279
- # @return [Array<String>] Attribute names
280
- def mobility_attributes
281
- mobility_modules.map(&:names).flatten.uniq
282
- end
283
-
284
- # Return true if attribute name is translated on this model.
285
- # @param [String, Symbol] Attribute name
286
- # @return [Boolean]
287
- def mobility_attribute?(name)
288
- mobility_attributes.include?(name.to_s)
289
- end
290
-
291
- # @!method translated_attribute_names
292
- # @return (see #mobility_attributes)
293
- alias translated_attribute_names mobility_attributes
294
-
295
- # Return backend class for a given attribute name.
296
- # @param [Symbol,String] Name of attribute
297
- # @return [Class] Backend class
298
- def mobility_backend_class(name)
299
- @backends ||= BackendsCache.new(self)
300
- @backends[name.to_sym]
301
- end
302
-
303
- class BackendsCache < Hash
304
- def initialize(klass)
305
- # Preload backend mapping
306
- klass.mobility_modules.each do |mod|
307
- mod.names.each { |name| self[name.to_sym] = mod.backend_class }
308
- end
309
-
310
- super() do |hash, name|
311
- if mod = klass.mobility_modules.find { |m| m.names.include? name.to_s }
312
- hash[name] = mod.backend_class
313
- else
314
- raise KeyError, "No backend for: #{name}."
315
- end
316
- end
317
- end
318
- end
319
- private_constant :BackendsCache
320
- end
321
- end
322
-
323
- class BackendRequired < ArgumentError; end
324
- end
@@ -1,44 +0,0 @@
1
- # frozen_string_literal: true
2
- module Mobility
3
- module Backend
4
- =begin
5
-
6
- Adds {#for} method to backend to return ORM-specific backend.
7
-
8
- @example KeyValue backend for AR model
9
- class Post < ActiveRecord::Base
10
- # ...
11
- end
12
- Mobility::Backends::KeyValue.for(Post)
13
- #=> Mobility::Backends::ActiveRecord::KeyValue
14
-
15
- =end
16
- module OrmDelegator
17
- # @param [Class] model_class Class of model
18
- # @return [Class] Class of backend to use for model
19
- def for(model_class)
20
- namespace = name.split('::')
21
- if Loaded::ActiveRecord && model_class < ::ActiveRecord::Base
22
- require_backend("active_record", namespace.last.underscore)
23
- const_get(namespace.insert(-2, "ActiveRecord").join("::"))
24
- elsif Loaded::Sequel && model_class < ::Sequel::Model
25
- require_backend("sequel", namespace.last.underscore)
26
- const_get(namespace.insert(-2, "Sequel").join("::"))
27
- else
28
- raise ArgumentError, "#{namespace.last} backend can only be used by ActiveRecord or Sequel models"
29
- end
30
- end
31
-
32
- private
33
-
34
- def require_backend(orm, backend)
35
- begin
36
- orm_backend = "mobility/backends/#{orm}/#{backend}"
37
- require orm_backend
38
- rescue LoadError => e
39
- raise unless e.message =~ /#{orm_backend}/
40
- end
41
- end
42
- end
43
- end
44
- end
@@ -1,50 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Mobility
4
- =begin
5
-
6
- Resets backend cache when reset events occur.
7
-
8
- @example Add trigger to call a method +my_backend_reset_method+ on backend instance when reset event(s) occurs on model
9
- resetter = Mobility::BackendResetter.for(MyModel).new(attributes) { my_backend_reset_method }
10
- MyModel.include(resetter)
11
-
12
- @see Mobility::ActiveRecord::BackendResetter
13
- @see Mobility::ActiveModel::BackendResetter
14
- @see Mobility::Sequel::BackendResetter
15
-
16
- =end
17
- class BackendResetter < Module
18
- # @param [Array<String>] attribute_names Names of attributes whose backends should be reset
19
- # @yield Backend to reset as context for block
20
- # @raise [ArgumentError] if no block is provided.
21
- def initialize(attribute_names, &block)
22
- raise ArgumentError, "block required" unless block_given?
23
- names = attribute_names.map(&:to_sym)
24
- @model_reset_method = Proc.new do
25
- names.each do |name|
26
- if @mobility_backends && @mobility_backends[name]
27
- @mobility_backends[name].instance_eval(&block)
28
- end
29
- end
30
- end
31
- end
32
-
33
- # Returns backend resetter class for model class
34
- # @param [Class] model_class Class of model to which backend resetter will be applied
35
- def self.for(model_class)
36
- if Loaded::ActiveRecord && model_class < ::ActiveRecord::Base
37
- require "mobility/active_record/backend_resetter"
38
- ActiveRecord::BackendResetter
39
- elsif Loaded::ActiveRecord && model_class.ancestors.include?(::ActiveModel::Dirty)
40
- require "mobility/active_model/backend_resetter"
41
- ActiveModel::BackendResetter
42
- elsif Loaded::Sequel && model_class < ::Sequel::Model
43
- require "mobility/sequel/backend_resetter"
44
- Sequel::BackendResetter
45
- else
46
- self
47
- end
48
- end
49
- end
50
- end
@@ -1,138 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Mobility
4
- =begin
5
-
6
- Stores shared Mobility configuration referenced by all backends.
7
-
8
- =end
9
- class Configuration
10
- RESERVED_OPTION_KEYS = %i[backend model_class].freeze
11
-
12
- # Alias for mobility_accessor (defaults to +translates+)
13
- # @return [Symbol]
14
- attr_accessor :accessor_method
15
-
16
- # Name of query scope/dataset method (defaults to +i18n+)
17
- # @return [Symbol]
18
- attr_accessor :query_method
19
-
20
- # Default set of options. These will be merged with any backend options
21
- # when defining translated attributes (with +translates+). Default options
22
- # may not include the keys 'backend' or 'model_class'.
23
- # @return [Hash]
24
- attr_reader :default_options
25
-
26
- # @deprecated The default_options= setter has been deprecated. Set each
27
- # option on the default_options hash instead.
28
- def default_options=(options)
29
- warn %{
30
- WARNING: The default_options= setter has been deprecated.
31
- Set each option on the default_options hash instead, like this:
32
-
33
- config.default_options[:fallbacks] = { ... }
34
- config.default_options[:dirty] = true
35
- }
36
- if (keys = options.keys & RESERVED_OPTION_KEYS).present?
37
- raise ReservedOptionKey,
38
- "Default options may not contain the following reserved keys: #{keys.join(', ')}"
39
- else
40
- @default_options = options
41
- end
42
- end
43
-
44
- # Plugins to apply. Order of plugins is important, as this becomes the
45
- # order in which plugins modules are included into the backend class or
46
- # attributes instance.
47
- # @return [Array<Symbol>]
48
- attr_accessor :plugins
49
-
50
- # Generate new fallbacks instance
51
- # @note This method will call the proc defined in the variable set by the
52
- # +fallbacks_generator=+ setter, passing the first argument to its `call`
53
- # method. By default the generator returns an instance of
54
- # +I18n::Locale::Fallbacks+.
55
- # @param fallbacks [Hash] Fallbacks hash passed to generator
56
- # @return [I18n::Locale::Fallbacks]
57
- def new_fallbacks(fallbacks = {})
58
- @fallbacks_generator.call(fallbacks)
59
- end
60
-
61
- # Assign proc which, passed a set of fallbacks, returns a default fallbacks
62
- # instance. By default this is a proc which takes fallbacks and returns an
63
- # instance of +I18n::Locale::Fallbacks+.
64
- # @param [Proc] fallbacks generator
65
- attr_writer :fallbacks_generator
66
-
67
- # @deprecated Use {#new_fallbacks} instead.
68
- def default_fallbacks(fallbacks = {})
69
- warn %{
70
- WARNING: The default_fallbacks configuration getter has been renamed
71
- new_fallbacks to avoid confusion. The original method default_fallbacks will be
72
- removed in the next major version of Mobility.
73
- }
74
- new_fallbacks(fallbacks)
75
- end
76
-
77
- # @deprecated Use {#fallbacks_generator=} instead.
78
- def default_fallbacks=(fallbacks)
79
- warn %{
80
- WARNING: The default_fallbacks= configuration setter has been renamed
81
- fallbacks_generator= to avoid confusion. The original method
82
- default_fallbacks= will be removed in the next major version of Mobility.
83
- }
84
- self.fallbacks_generator = fallbacks
85
- end
86
-
87
- # Default backend to use (can be symbol or actual backend class)
88
- # @return [Symbol,Class]
89
- attr_accessor :default_backend
90
-
91
- # Returns set of default accessor locles to use (defaults to
92
- # +I18n.available_locales+)
93
- # @return [Array<Symbol>]
94
- def default_accessor_locales
95
- if @default_accessor_locales.is_a?(Proc)
96
- @default_accessor_locales.call
97
- else
98
- @default_accessor_locales
99
- end
100
- end
101
- attr_writer :default_accessor_locales
102
-
103
- def initialize
104
- @accessor_method = :translates
105
- @query_method = :i18n
106
- @fallbacks_generator = lambda { |fallbacks| Mobility::Fallbacks.build(fallbacks) }
107
- @default_accessor_locales = lambda { Mobility.available_locales }
108
- @default_options = Options[{
109
- cache: true,
110
- presence: true,
111
- query: true,
112
- default: Plugins::OPTION_UNSET
113
- }]
114
- @plugins = %i[
115
- query
116
- cache
117
- dirty
118
- fallbacks
119
- presence
120
- default
121
- attribute_methods
122
- fallthrough_accessors
123
- locale_accessors
124
- ]
125
- end
126
-
127
- class ReservedOptionKey < Exception; end
128
-
129
- class Options < Hash
130
- def []=(key, _)
131
- if RESERVED_OPTION_KEYS.include?(key)
132
- raise Configuration::ReservedOptionKey, "Default options may not contain the following reserved key: #{key}"
133
- end
134
- super
135
- end
136
- end
137
- end
138
- end