mobility 0.6.0 → 0.7.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.
Files changed (66) hide show
  1. checksums.yaml +5 -5
  2. checksums.yaml.gz.sig +3 -2
  3. data.tar.gz.sig +0 -0
  4. data/CHANGELOG.md +39 -1
  5. data/Gemfile.lock +65 -10
  6. data/README.md +63 -27
  7. data/lib/mobility.rb +16 -31
  8. data/lib/mobility/active_record.rb +2 -12
  9. data/lib/mobility/active_record/uniqueness_validator.rb +9 -8
  10. data/lib/mobility/arel.rb +20 -0
  11. data/lib/mobility/arel/nodes.rb +16 -0
  12. data/lib/mobility/arel/nodes/pg_ops.rb +136 -0
  13. data/lib/mobility/arel/visitor.rb +61 -0
  14. data/lib/mobility/attributes.rb +82 -19
  15. data/lib/mobility/backend.rb +53 -8
  16. data/lib/mobility/backend_resetter.rb +2 -1
  17. data/lib/mobility/backends/active_record.rb +31 -11
  18. data/lib/mobility/backends/active_record/column.rb +7 -3
  19. data/lib/mobility/backends/active_record/container.rb +23 -21
  20. data/lib/mobility/backends/active_record/hstore.rb +11 -6
  21. data/lib/mobility/backends/active_record/json.rb +22 -16
  22. data/lib/mobility/backends/active_record/jsonb.rb +22 -16
  23. data/lib/mobility/backends/active_record/key_value.rb +123 -15
  24. data/lib/mobility/backends/active_record/pg_hash.rb +1 -2
  25. data/lib/mobility/backends/active_record/serialized.rb +7 -6
  26. data/lib/mobility/backends/active_record/table.rb +145 -24
  27. data/lib/mobility/backends/hash_valued.rb +15 -10
  28. data/lib/mobility/backends/key_value.rb +12 -12
  29. data/lib/mobility/backends/sequel/container.rb +3 -9
  30. data/lib/mobility/backends/sequel/hstore.rb +2 -2
  31. data/lib/mobility/backends/sequel/json.rb +15 -15
  32. data/lib/mobility/backends/sequel/jsonb.rb +14 -14
  33. data/lib/mobility/backends/sequel/key_value.rb +0 -11
  34. data/lib/mobility/backends/sequel/pg_hash.rb +2 -3
  35. data/lib/mobility/backends/sequel/pg_query_methods.rb +1 -1
  36. data/lib/mobility/backends/sequel/query_methods.rb +3 -3
  37. data/lib/mobility/backends/sequel/serialized.rb +2 -2
  38. data/lib/mobility/backends/sequel/table.rb +10 -11
  39. data/lib/mobility/backends/table.rb +17 -8
  40. data/lib/mobility/configuration.rb +4 -1
  41. data/lib/mobility/interface.rb +0 -0
  42. data/lib/mobility/plugins.rb +1 -0
  43. data/lib/mobility/plugins/active_record/query.rb +192 -0
  44. data/lib/mobility/plugins/cache.rb +1 -2
  45. data/lib/mobility/plugins/default.rb +28 -14
  46. data/lib/mobility/plugins/fallbacks.rb +1 -1
  47. data/lib/mobility/plugins/locale_accessors.rb +13 -9
  48. data/lib/mobility/plugins/presence.rb +15 -7
  49. data/lib/mobility/plugins/query.rb +28 -0
  50. data/lib/mobility/translates.rb +9 -9
  51. data/lib/mobility/version.rb +1 -1
  52. data/lib/rails/generators/mobility/templates/initializer.rb +1 -0
  53. metadata +10 -15
  54. metadata.gz.sig +0 -0
  55. data/lib/mobility/accumulator.rb +0 -33
  56. data/lib/mobility/adapter.rb +0 -20
  57. data/lib/mobility/backends/active_record/column/query_methods.rb +0 -42
  58. data/lib/mobility/backends/active_record/container/json_query_methods.rb +0 -36
  59. data/lib/mobility/backends/active_record/container/jsonb_query_methods.rb +0 -33
  60. data/lib/mobility/backends/active_record/hstore/query_methods.rb +0 -25
  61. data/lib/mobility/backends/active_record/json/query_methods.rb +0 -30
  62. data/lib/mobility/backends/active_record/jsonb/query_methods.rb +0 -26
  63. data/lib/mobility/backends/active_record/key_value/query_methods.rb +0 -76
  64. data/lib/mobility/backends/active_record/pg_query_methods.rb +0 -154
  65. data/lib/mobility/backends/active_record/serialized/query_methods.rb +0 -34
  66. data/lib/mobility/backends/active_record/table/query_methods.rb +0 -105
@@ -18,7 +18,7 @@ created for the model with the hash defining additional fallbacks. To set a
18
18
  default value for this hash, use set the value of `default_options[:fallbacks]`
19
19
  in your Mobility configuration (see below).
20
20
 
21
- In addition, fallbacks are disabled in certain situation. To explicitly disable
21
+ In addition, fallbacks are disabled in certain situations. To explicitly disable
22
22
  fallbacks when reading and writing, you can pass the <tt>fallback: false</tt>
23
23
  option to the reader method. This can be useful to determine the actual
24
24
  value of the translated attribute, including a possible +nil+ value.
@@ -56,28 +56,32 @@ If no locales are passed as an option to the initializer,
56
56
  warning_message = "locale passed as option to locale accessor will be ignored"
57
57
  normalized_locale = Mobility.normalize_locale(locale)
58
58
 
59
- define_method "#{name}_#{normalized_locale}" do |**options|
59
+ module_eval <<-EOM, __FILE__, __LINE__ + 1
60
+ def #{name}_#{normalized_locale}(options = {})
60
61
  return super() if options.delete(:super)
61
- warn warning_message if options[:locale]
62
- public_send(name, **options, locale: locale)
62
+ warn "#{warning_message}" if options[:locale]
63
+ #{name}(**options, locale: :'#{locale}')
63
64
  end
64
65
 
65
- define_method "#{name}_#{normalized_locale}?" do |**options|
66
+ def #{name}_#{normalized_locale}?(options = {})
66
67
  return super() if options.delete(:super)
67
- warn warning_message if options[:locale]
68
- public_send("#{name}?", **options, locale: locale)
68
+ warn "#{warning_message}" if options[:locale]
69
+ #{name}?(**options, locale: :'#{locale}')
69
70
  end
71
+ EOM
70
72
  end
71
73
 
72
74
  def define_writer(name, locale)
73
75
  warning_message = "locale passed as option to locale accessor will be ignored"
74
76
  normalized_locale = Mobility.normalize_locale(locale)
75
77
 
76
- define_method "#{name}_#{normalized_locale}=" do |value, **options|
78
+ module_eval <<-EOM, __FILE__, __LINE__ + 1
79
+ def #{name}_#{normalized_locale}=(value, options = {})
77
80
  return super(value) if options.delete(:super)
78
- warn warning_message if options[:locale]
79
- public_send("#{name}=", value, **options, locale: locale)
81
+ warn "#{warning_message}" if options[:locale]
82
+ public_send(:#{name}=, value, **options, locale: :'#{locale}')
80
83
  end
84
+ EOM
81
85
  end
82
86
  end
83
87
  end
@@ -8,6 +8,9 @@ module Mobility
8
8
  Applies presence filter to values fetched from backend and to values set on
9
9
  backend. Included by default, but can be disabled with +presence: false+ option.
10
10
 
11
+ @note For performance reasons, the presence plugin filters only for empty
12
+ strings, not other values continued "blank" like empty arrays.
13
+
11
14
  =end
12
15
  module Presence
13
16
  # Applies presence plugin to attributes.
@@ -17,23 +20,28 @@ backend. Included by default, but can be disabled with +presence: false+ option.
17
20
  attributes.backend_class.include(self) if option
18
21
  end
19
22
 
20
- # @group Backend Accessors
23
+ # @!group Backend Accessors
21
24
  # @!macro backend_reader
22
25
  # @option options [Boolean] presence
23
26
  # *false* to disable presence filter.
24
27
  def read(locale, **options)
25
- return super if options.delete(:presence) == false
26
- value = super
27
- value == false ? value : Util.presence(value)
28
+ options.delete(:presence) == false ? super : Presence[super]
28
29
  end
29
30
 
30
- # @group Backend Accessors
31
31
  # @!macro backend_writer
32
32
  # @option options [Boolean] presence
33
33
  # *false* to disable presence filter.
34
34
  def write(locale, value, **options)
35
- return super if options.delete(:presence) == false
36
- super(locale, value == false ? value : Util.presence(value), options)
35
+ if options.delete(:presence) == false
36
+ super
37
+ else
38
+ super(locale, Presence[value], options)
39
+ end
40
+ end
41
+ # @!endgroup
42
+
43
+ def self.[](value)
44
+ (value == "") ? nil : value
37
45
  end
38
46
  end
39
47
  end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+ module Mobility
3
+ module Plugins
4
+ =begin
5
+
6
+ @see {Mobility::Plugins::ActiveRecord::Query}
7
+
8
+ =end
9
+ module Query
10
+ class << self
11
+ def apply(attributes, option)
12
+ if option
13
+ include_query_module(attributes)
14
+ end
15
+ end
16
+
17
+ private
18
+
19
+ def include_query_module(attributes)
20
+ if Loaded::ActiveRecord && attributes.model_class < ::ActiveRecord::Base
21
+ require "mobility/plugins/active_record/query"
22
+ ActiveRecord::Query.apply(attributes)
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -44,22 +44,22 @@ passed to accessors to configure backend (see example below).
44
44
  =end
45
45
  module Translates
46
46
  # Defines mobility accessor on model class.
47
- # @param [Array<String>] attributes
48
- # @param [Hash] options
49
- # @yield Yields to block with backend as context
50
47
  # @!method mobility_accessor(*attributes, **options)
48
+ # @param [Array<String>] attributes
49
+ # @param [Hash] options
50
+ # @yield Yields to block with backend as context
51
51
 
52
52
  # Defines mobility reader and presence method on model class.
53
- # @param [Array<String>] attributes
54
- # @param [Hash] options
55
- # @yield Yields to block with backend as context
56
53
  # @!method mobility_reader(*attributes, **options)
54
+ # @param [Array<String>] attributes
55
+ # @param [Hash] options
56
+ # @yield Yields to block with backend as context
57
57
 
58
58
  # Defines mobility writer on model class.
59
- # @param [Array<String>] attributes
60
- # @param [Hash] options
61
- # @yield Yields to block with backend as context
62
59
  # @!method mobility_writer(*attributes, **options)
60
+ # @param [Array<String>] attributes
61
+ # @param [Hash] options
62
+ # @yield Yields to block with backend as context
63
63
  %w[accessor reader writer].each do |method|
64
64
  class_eval <<-EOM, __FILE__, __LINE__ + 1
65
65
  def mobility_#{method}(*args, **options, &block)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Mobility
4
- VERSION = "0.6.0"
4
+ VERSION = "0.7.0"
5
5
  end
@@ -21,6 +21,7 @@ Mobility.configure do |config|
21
21
  # ignored by models. (In most cases, you probably don't want to change this.)
22
22
  #
23
23
  # config.plugins = %i[
24
+ # query
24
25
  # cache
25
26
  # dirty
26
27
  # fallbacks
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mobility
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.0
4
+ version: 0.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chris Salzberg
@@ -30,7 +30,7 @@ cert_chain:
30
30
  eGDROPZoL5RXwiOnRbexxa7dcAxMrDfGB/hpiunIPWPsi4n5P7K/6OO/sGVMl9xv
31
31
  SZBPXjzrHdyOFLBYXB+PG7s3F/4=
32
32
  -----END CERTIFICATE-----
33
- date: 2018-04-26 00:00:00.000000000 Z
33
+ date: 2018-05-30 00:00:00.000000000 Z
34
34
  dependencies:
35
35
  - !ruby/object:Gem::Dependency
36
36
  name: request_store
@@ -166,7 +166,6 @@ files:
166
166
  - README.md
167
167
  - Rakefile
168
168
  - lib/mobility.rb
169
- - lib/mobility/accumulator.rb
170
169
  - lib/mobility/active_model.rb
171
170
  - lib/mobility/active_model/backend_resetter.rb
172
171
  - lib/mobility/active_record.rb
@@ -176,7 +175,10 @@ files:
176
175
  - lib/mobility/active_record/text_translation.rb
177
176
  - lib/mobility/active_record/translation.rb
178
177
  - lib/mobility/active_record/uniqueness_validator.rb
179
- - lib/mobility/adapter.rb
178
+ - lib/mobility/arel.rb
179
+ - lib/mobility/arel/nodes.rb
180
+ - lib/mobility/arel/nodes/pg_ops.rb
181
+ - lib/mobility/arel/visitor.rb
180
182
  - lib/mobility/attributes.rb
181
183
  - lib/mobility/backend.rb
182
184
  - lib/mobility/backend/orm_delegator.rb
@@ -184,25 +186,15 @@ files:
184
186
  - lib/mobility/backends.rb
185
187
  - lib/mobility/backends/active_record.rb
186
188
  - lib/mobility/backends/active_record/column.rb
187
- - lib/mobility/backends/active_record/column/query_methods.rb
188
189
  - lib/mobility/backends/active_record/container.rb
189
- - lib/mobility/backends/active_record/container/json_query_methods.rb
190
- - lib/mobility/backends/active_record/container/jsonb_query_methods.rb
191
190
  - lib/mobility/backends/active_record/hstore.rb
192
- - lib/mobility/backends/active_record/hstore/query_methods.rb
193
191
  - lib/mobility/backends/active_record/json.rb
194
- - lib/mobility/backends/active_record/json/query_methods.rb
195
192
  - lib/mobility/backends/active_record/jsonb.rb
196
- - lib/mobility/backends/active_record/jsonb/query_methods.rb
197
193
  - lib/mobility/backends/active_record/key_value.rb
198
- - lib/mobility/backends/active_record/key_value/query_methods.rb
199
194
  - lib/mobility/backends/active_record/pg_hash.rb
200
- - lib/mobility/backends/active_record/pg_query_methods.rb
201
195
  - lib/mobility/backends/active_record/query_methods.rb
202
196
  - lib/mobility/backends/active_record/serialized.rb
203
- - lib/mobility/backends/active_record/serialized/query_methods.rb
204
197
  - lib/mobility/backends/active_record/table.rb
205
- - lib/mobility/backends/active_record/table/query_methods.rb
206
198
  - lib/mobility/backends/column.rb
207
199
  - lib/mobility/backends/container.rb
208
200
  - lib/mobility/backends/hash_valued.rb
@@ -236,6 +228,7 @@ files:
236
228
  - lib/mobility/backends/table.rb
237
229
  - lib/mobility/configuration.rb
238
230
  - lib/mobility/fallbacks.rb
231
+ - lib/mobility/interface.rb
239
232
  - lib/mobility/loaded.rb
240
233
  - lib/mobility/plugins.rb
241
234
  - lib/mobility/plugins/active_model.rb
@@ -243,6 +236,7 @@ files:
243
236
  - lib/mobility/plugins/active_record.rb
244
237
  - lib/mobility/plugins/active_record/attribute_methods.rb
245
238
  - lib/mobility/plugins/active_record/dirty.rb
239
+ - lib/mobility/plugins/active_record/query.rb
246
240
  - lib/mobility/plugins/attribute_methods.rb
247
241
  - lib/mobility/plugins/cache.rb
248
242
  - lib/mobility/plugins/cache/translation_cacher.rb
@@ -252,6 +246,7 @@ files:
252
246
  - lib/mobility/plugins/fallthrough_accessors.rb
253
247
  - lib/mobility/plugins/locale_accessors.rb
254
248
  - lib/mobility/plugins/presence.rb
249
+ - lib/mobility/plugins/query.rb
255
250
  - lib/mobility/plugins/sequel.rb
256
251
  - lib/mobility/plugins/sequel/dirty.rb
257
252
  - lib/mobility/sequel.rb
@@ -299,7 +294,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
299
294
  version: '0'
300
295
  requirements: []
301
296
  rubyforge_project:
302
- rubygems_version: 2.6.11
297
+ rubygems_version: 2.7.3
303
298
  signing_key:
304
299
  specification_version: 4
305
300
  summary: Pluggable Ruby translation framework
metadata.gz.sig CHANGED
Binary file
@@ -1,33 +0,0 @@
1
- module Mobility
2
- =begin
3
-
4
- Class to access Mobility across backends. In particular, keeps a record of
5
- which {Attributes} modules have been included on the model class.
6
-
7
- =end
8
- class Accumulator
9
- # @return [Array<Attributes>]
10
- attr_reader :modules
11
-
12
- # @param [Class] model_class Model class
13
- def initialize
14
- @modules = []
15
- end
16
-
17
- # @return [Array<String>] Translated attributes defined on model
18
- def translated_attribute_names
19
- modules.map(&:names).flatten
20
- end
21
-
22
- # Appends backend module to +modules+ array for later reference.
23
- # @param [Attributes] backend_module Attributes module
24
- def << backend_module
25
- modules << backend_module
26
- end
27
-
28
- def initialize_dup(other)
29
- @modules = other.modules.dup
30
- super
31
- end
32
- end
33
- end
@@ -1,20 +0,0 @@
1
- module Mobility
2
- =begin
3
-
4
- Provides interface to access attributes across all backends of an instance.
5
-
6
- =end
7
- class Adapter
8
- # @param [Object] model Instance of model class
9
- def initialize(model)
10
- @model = model
11
- end
12
-
13
- # Fetch backend for an attribute
14
- # @param [String] attribute Attribute
15
- def backend_for(attribute)
16
- @model.send(Backend.method_name(attribute))
17
- end
18
- end
19
- private_constant :Adapter
20
- end
@@ -1,42 +0,0 @@
1
- # frozen_string_literal: true
2
- require "mobility/backends/active_record/query_methods"
3
-
4
- module Mobility
5
- module Backends
6
- module ActiveRecord
7
- class Column::QueryMethods < QueryMethods
8
- def initialize(attributes, _)
9
- super
10
- q = self
11
-
12
- define_method :where! do |opts, *rest|
13
- super(q.convert_opts(opts), *rest)
14
- end
15
- end
16
-
17
- def extended(relation)
18
- super
19
- q = self
20
-
21
- mod = Module.new do
22
- define_method :not do |opts, *rest|
23
- super(q.convert_opts(opts), *rest)
24
- end
25
- end
26
- relation.mobility_where_chain.include(mod)
27
- end
28
-
29
- def convert_opts(opts)
30
- if i18n_keys = extract_attributes(opts)
31
- opts = opts.with_indifferent_access
32
- i18n_keys.each do |attr|
33
- opts[Backends::Column.column_name_for(attr)] = collapse opts.delete(attr)
34
- end
35
- end
36
- opts
37
- end
38
- end
39
- Column.private_constant :QueryMethods
40
- end
41
- end
42
- end
@@ -1,36 +0,0 @@
1
- # frozen_string_literal: true
2
- require 'mobility/backends/active_record/pg_query_methods'
3
- require "mobility/backends/active_record/query_methods"
4
-
5
- module Mobility
6
- module Backends
7
- module ActiveRecord
8
- class Container::JsonQueryMethods < QueryMethods
9
- include PgQueryMethods
10
- attr_reader :column_name, :column
11
-
12
- def initialize(_attributes, options)
13
- super
14
- @column = arel_table[options[:column_name]]
15
- end
16
-
17
- def matches(key, locale)
18
- build_infix(:'->>', build_infix(:'->', column, build_quoted(locale)), build_quoted(key))
19
- end
20
-
21
- def exists(key, locale)
22
- matches(key, locale).eq(nil).not
23
- end
24
-
25
- def absent(key, locale)
26
- matches(key, locale).eq(nil)
27
- end
28
-
29
- def quote(value)
30
- value.to_s
31
- end
32
- end
33
- Container.private_constant :JsonQueryMethods
34
- end
35
- end
36
- end
@@ -1,33 +0,0 @@
1
- # frozen_string_literal: true
2
- require 'mobility/backends/active_record/pg_query_methods'
3
- require "mobility/backends/active_record/query_methods"
4
-
5
- module Mobility
6
- module Backends
7
- module ActiveRecord
8
- class Container::JsonbQueryMethods < QueryMethods
9
- include PgQueryMethods
10
- attr_reader :column
11
-
12
- def initialize(_attributes, options)
13
- super
14
- @column = arel_table[options[:column_name]]
15
- end
16
-
17
- def matches(key, locale)
18
- build_infix(:'->', build_infix(:'->', column, build_quoted(locale)), build_quoted(key))
19
- end
20
-
21
- def exists(key, locale)
22
- build_infix(:'?', column, build_quoted(locale)).and(
23
- build_infix(:'?', build_infix(:'->', column, build_quoted(locale)), build_quoted(key)))
24
- end
25
-
26
- def quote(value)
27
- build_quoted(value.to_json)
28
- end
29
- end
30
- Container.private_constant :JsonbQueryMethods
31
- end
32
- end
33
- end