mobility 0.8.8 → 1.0.0.alpha

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 (96) 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 +56 -0
  5. data/Gemfile +52 -16
  6. data/Gemfile.lock +113 -52
  7. data/Guardfile +23 -1
  8. data/README.md +184 -92
  9. data/Rakefile +6 -4
  10. data/lib/mobility.rb +40 -166
  11. data/lib/mobility/active_record/translation.rb +1 -1
  12. data/lib/mobility/arel/nodes/pg_ops.rb +1 -1
  13. data/lib/mobility/backend.rb +19 -41
  14. data/lib/mobility/backends.rb +20 -0
  15. data/lib/mobility/backends/active_record.rb +4 -0
  16. data/lib/mobility/backends/active_record/column.rb +2 -0
  17. data/lib/mobility/backends/active_record/container.rb +4 -2
  18. data/lib/mobility/backends/active_record/hstore.rb +2 -0
  19. data/lib/mobility/backends/active_record/json.rb +2 -0
  20. data/lib/mobility/backends/active_record/jsonb.rb +2 -0
  21. data/lib/mobility/backends/active_record/key_value.rb +5 -3
  22. data/lib/mobility/backends/active_record/pg_hash.rb +1 -1
  23. data/lib/mobility/backends/active_record/serialized.rb +2 -0
  24. data/lib/mobility/backends/active_record/table.rb +5 -3
  25. data/lib/mobility/backends/column.rb +0 -6
  26. data/lib/mobility/backends/container.rb +2 -1
  27. data/lib/mobility/backends/hash.rb +39 -0
  28. data/lib/mobility/backends/hstore.rb +0 -1
  29. data/lib/mobility/backends/json.rb +0 -1
  30. data/lib/mobility/backends/jsonb.rb +0 -1
  31. data/lib/mobility/backends/key_value.rb +22 -14
  32. data/lib/mobility/backends/null.rb +2 -0
  33. data/lib/mobility/backends/sequel.rb +3 -0
  34. data/lib/mobility/backends/sequel/column.rb +2 -0
  35. data/lib/mobility/backends/sequel/container.rb +3 -1
  36. data/lib/mobility/backends/sequel/hstore.rb +2 -0
  37. data/lib/mobility/backends/sequel/json.rb +2 -0
  38. data/lib/mobility/backends/sequel/jsonb.rb +3 -1
  39. data/lib/mobility/backends/sequel/key_value.rb +8 -6
  40. data/lib/mobility/backends/sequel/serialized.rb +2 -0
  41. data/lib/mobility/backends/sequel/table.rb +5 -2
  42. data/lib/mobility/backends/serialized.rb +1 -3
  43. data/lib/mobility/backends/table.rb +14 -6
  44. data/lib/mobility/pluggable.rb +36 -0
  45. data/lib/mobility/plugin.rb +260 -0
  46. data/lib/mobility/plugins.rb +26 -25
  47. data/lib/mobility/plugins/active_model.rb +17 -0
  48. data/lib/mobility/plugins/active_model/cache.rb +26 -0
  49. data/lib/mobility/plugins/active_model/dirty.rb +310 -54
  50. data/lib/mobility/plugins/active_record.rb +34 -0
  51. data/lib/mobility/plugins/active_record/backend.rb +25 -0
  52. data/lib/mobility/plugins/active_record/cache.rb +28 -0
  53. data/lib/mobility/plugins/active_record/dirty.rb +72 -101
  54. data/lib/mobility/plugins/active_record/query.rb +48 -34
  55. data/lib/mobility/plugins/active_record/uniqueness_validation.rb +60 -0
  56. data/lib/mobility/plugins/attribute_methods.rb +28 -20
  57. data/lib/mobility/plugins/attributes.rb +70 -0
  58. data/lib/mobility/plugins/backend.rb +138 -0
  59. data/lib/mobility/plugins/backend_reader.rb +34 -0
  60. data/lib/mobility/plugins/cache.rb +59 -24
  61. data/lib/mobility/plugins/default.rb +22 -17
  62. data/lib/mobility/plugins/dirty.rb +12 -33
  63. data/lib/mobility/plugins/fallbacks.rb +51 -43
  64. data/lib/mobility/plugins/fallthrough_accessors.rb +26 -25
  65. data/lib/mobility/plugins/locale_accessors.rb +25 -35
  66. data/lib/mobility/plugins/presence.rb +28 -21
  67. data/lib/mobility/plugins/query.rb +8 -17
  68. data/lib/mobility/plugins/reader.rb +50 -0
  69. data/lib/mobility/plugins/sequel.rb +34 -0
  70. data/lib/mobility/plugins/sequel/backend.rb +25 -0
  71. data/lib/mobility/plugins/sequel/cache.rb +24 -0
  72. data/lib/mobility/plugins/sequel/dirty.rb +45 -32
  73. data/lib/mobility/plugins/sequel/query.rb +21 -6
  74. data/lib/mobility/plugins/writer.rb +44 -0
  75. data/lib/mobility/translations.rb +95 -0
  76. data/lib/mobility/version.rb +12 -1
  77. data/lib/rails/generators/mobility/templates/initializer.rb +95 -77
  78. metadata +51 -51
  79. metadata.gz.sig +0 -0
  80. data/lib/mobility/active_model.rb +0 -4
  81. data/lib/mobility/active_model/backend_resetter.rb +0 -26
  82. data/lib/mobility/active_record.rb +0 -23
  83. data/lib/mobility/active_record/backend_resetter.rb +0 -26
  84. data/lib/mobility/active_record/uniqueness_validator.rb +0 -60
  85. data/lib/mobility/attributes.rb +0 -324
  86. data/lib/mobility/backend/orm_delegator.rb +0 -44
  87. data/lib/mobility/backend_resetter.rb +0 -50
  88. data/lib/mobility/configuration.rb +0 -138
  89. data/lib/mobility/fallbacks.rb +0 -28
  90. data/lib/mobility/interface.rb +0 -0
  91. data/lib/mobility/loaded.rb +0 -4
  92. data/lib/mobility/plugins/active_record/attribute_methods.rb +0 -38
  93. data/lib/mobility/plugins/cache/translation_cacher.rb +0 -40
  94. data/lib/mobility/sequel.rb +0 -9
  95. data/lib/mobility/sequel/backend_resetter.rb +0 -23
  96. data/lib/mobility/translates.rb +0 -73
@@ -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
@@ -1,28 +0,0 @@
1
- module Mobility
2
- =begin
3
-
4
- Subclasses +I18n::Locale::Fallbacks+ such that instances of this class
5
- fall through to fallbacks defined in +I18n.fallbacks+. This allows models to
6
- customize fallbacks while still falling through to any fallbacks defined
7
- globally.
8
-
9
- =end
10
- class Fallbacks < ::I18n::Locale::Fallbacks
11
- # @param [Symbol] locale
12
- # @return [Array] locales
13
- def [](locale)
14
- super | I18n.fallbacks[locale]
15
- end
16
-
17
- # For this set of fallbacks, return a new fallbacks hash.
18
- # @param [Hash] fallbacks
19
- # @return [I18n::Locale::Fallbacks,Mobility::Fallbacks] fallbacks hash
20
- def self.build(fallbacks)
21
- if I18n.respond_to?(:fallbacks)
22
- new(fallbacks)
23
- else
24
- I18n::Locale::Fallbacks.new(fallbacks)
25
- end
26
- end
27
- end
28
- end
File without changes
@@ -1,4 +0,0 @@
1
- module Mobility
2
- module Loaded
3
- end
4
- end
@@ -1,38 +0,0 @@
1
- module Mobility
2
- module Plugins
3
- module ActiveRecord
4
- module TranslatedAttributes
5
- def translated_attributes
6
- {}
7
- end
8
-
9
- def attributes
10
- super.merge(translated_attributes)
11
- end
12
- end
13
-
14
- =begin
15
-
16
- Module builder adding translated attributes to #attributes hash on model
17
- instance. See {Mobility::Plugins::AttributeMethods} for further details.
18
-
19
- =end
20
- class AttributeMethods < Module
21
- def initialize(*attribute_names)
22
- include TranslatedAttributes
23
- define_method :translated_attributes do
24
- super().merge(attribute_names.inject({}) do |attributes, name|
25
- attributes.merge(name.to_s => send(name))
26
- end)
27
- end
28
- end
29
-
30
- def included(model_class)
31
- model_class.class_eval do
32
- define_method :untranslated_attributes, ::ActiveRecord::Base.instance_method(:attributes)
33
- end
34
- end
35
- end
36
- end
37
- end
38
- end
@@ -1,40 +0,0 @@
1
- module Mobility
2
- module Plugins
3
- module Cache
4
- =begin
5
-
6
- Creates a module to cache a given translation fetch method. The cacher defines
7
- private methods +cache+ and +clear_cache+ to access and clear, respectively, a
8
- translations hash.
9
-
10
- This cacher is used to cache translation values in {Mobility::Plugins::Cache},
11
- and also to cache translation *records* in {Mobility::Backends::Table} and
12
- {Mobility::Backends::KeyValue}.
13
-
14
- =end
15
- class TranslationCacher < Module
16
- # @param [Symbol] fetch_method Name of translation fetch method to cache
17
- def initialize(fetch_method)
18
- class_eval <<-EOM, __FILE__, __LINE__ + 1
19
- def #{fetch_method} locale, **options
20
- return super(locale, options) if options.delete(:cache) == false
21
- if cache.has_key?(locale)
22
- cache[locale]
23
- else
24
- cache[locale] = super(locale, options)
25
- end
26
- end
27
- EOM
28
-
29
- include CacheMethods
30
- end
31
-
32
- module CacheMethods
33
- private
34
- def cache; @cache ||= {}; end
35
- def clear_cache; @cache = {}; end
36
- end
37
- end
38
- end
39
- end
40
- end
@@ -1,9 +0,0 @@
1
- module Mobility
2
- =begin
3
-
4
- Module loading Sequel-specific classes for Mobility models.
5
-
6
- =end
7
- module Sequel
8
- end
9
- end
@@ -1,23 +0,0 @@
1
- module Mobility
2
- module Sequel
3
- =begin
4
-
5
- Backend resetter for Sequel models. Triggers backend reset when +refresh+
6
- method is called.
7
-
8
- =end
9
- class BackendResetter < Mobility::BackendResetter
10
-
11
- # (see Mobility::BackendResetter#initialize)
12
- def initialize(attribute_names, &block)
13
- super
14
-
15
- model_reset_method = @model_reset_method
16
-
17
- define_method :refresh do
18
- super().tap { instance_eval(&model_reset_method) }
19
- end
20
- end
21
- end
22
- end
23
- end
@@ -1,73 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Mobility
4
- =begin
5
-
6
- Defines methods for attaching backends to a class. A block can optionally be
7
- passed to accessors to configure backend (see example below).
8
-
9
- @example Defining backend on a class
10
- class MyClass
11
- extend Translates
12
- mobility_accessor :foo, option: :value
13
- end
14
-
15
- @example Passing backend to a block
16
- class MyClass
17
- extend Translates
18
- mobility_accessor :foo, option: :value do
19
- # add custom code to backend class for this attribute only
20
- end
21
- end
22
-
23
- @example Defining only a backend reader and presence method
24
- class MyClass
25
- extend Translates
26
- mobility_reader :foo
27
- end
28
-
29
- instance = MyClass.new
30
- instance.foo #=> (some value)
31
- instance.foo? #=> true
32
- instance.foo = "foo" #=> NoMethodError
33
-
34
- @example Defining only a backend writer
35
- class MyClass
36
- extend Translates
37
- mobility_writer :foo
38
- end
39
-
40
- instance = MyClass.new
41
- instance.foo #=> NoMethodError
42
- instance.foo? #=> NoMethodError
43
- instance.foo = "foo" #=> (sets attribute to value "foo")
44
- =end
45
- module Translates
46
- # Defines mobility accessor on model class.
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
-
52
- # Defines mobility reader and presence method on model class.
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
-
58
- # Defines mobility writer on model class.
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
- %w[accessor reader writer].each do |method|
64
- class_eval <<-EOM, __FILE__, __LINE__ + 1
65
- def mobility_#{method}(*args, **options, &block)
66
- attributes = Attributes.new(*args, method: :#{method}, **options)
67
- attributes.backend.instance_eval(&block) if block_given?
68
- include attributes
69
- end
70
- EOM
71
- end
72
- end
73
- end