mobility 1.0.0.beta1 → 1.0.2

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 (55) 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 +53 -3
  5. data/Gemfile +5 -16
  6. data/Gemfile.lock +20 -3
  7. data/README.md +23 -28
  8. data/lib/mobility.rb +61 -7
  9. data/lib/mobility/backends/active_record.rb +1 -1
  10. data/lib/mobility/backends/active_record/column.rb +1 -1
  11. data/lib/mobility/backends/active_record/container.rb +4 -4
  12. data/lib/mobility/backends/active_record/hstore.rb +3 -3
  13. data/lib/mobility/backends/active_record/json.rb +3 -3
  14. data/lib/mobility/backends/active_record/jsonb.rb +3 -3
  15. data/lib/mobility/backends/active_record/key_value.rb +27 -11
  16. data/lib/mobility/backends/active_record/table.rb +11 -6
  17. data/lib/mobility/backends/sequel.rb +32 -0
  18. data/lib/mobility/backends/sequel/container.rb +5 -3
  19. data/lib/mobility/backends/sequel/key_value.rb +79 -12
  20. data/lib/mobility/backends/sequel/pg_hash.rb +6 -6
  21. data/lib/mobility/backends/sequel/table.rb +18 -8
  22. data/lib/mobility/backends/table.rb +11 -6
  23. data/lib/mobility/plugin.rb +2 -2
  24. data/lib/mobility/plugins/active_record.rb +3 -0
  25. data/lib/mobility/plugins/active_record/backend.rb +2 -0
  26. data/lib/mobility/plugins/active_record/query.rb +7 -7
  27. data/lib/mobility/plugins/active_record/uniqueness_validation.rb +4 -0
  28. data/lib/mobility/plugins/arel.rb +125 -0
  29. data/lib/mobility/plugins/arel/nodes.rb +15 -0
  30. data/lib/mobility/plugins/arel/nodes/pg_ops.rb +134 -0
  31. data/lib/mobility/plugins/attribute_methods.rb +1 -0
  32. data/lib/mobility/plugins/attributes.rb +17 -15
  33. data/lib/mobility/plugins/backend.rb +7 -7
  34. data/lib/mobility/plugins/sequel/dirty.rb +1 -1
  35. data/lib/mobility/version.rb +2 -2
  36. data/lib/rails/generators/mobility/templates/create_string_translations.rb +0 -1
  37. data/lib/rails/generators/mobility/templates/create_text_translations.rb +0 -1
  38. data/lib/rails/generators/mobility/templates/initializer.rb +9 -1
  39. metadata +14 -20
  40. metadata.gz.sig +0 -0
  41. data/lib/mobility/active_record/model_translation.rb +0 -14
  42. data/lib/mobility/active_record/string_translation.rb +0 -10
  43. data/lib/mobility/active_record/text_translation.rb +0 -10
  44. data/lib/mobility/active_record/translation.rb +0 -14
  45. data/lib/mobility/arel.rb +0 -49
  46. data/lib/mobility/arel/nodes.rb +0 -13
  47. data/lib/mobility/arel/nodes/pg_ops.rb +0 -132
  48. data/lib/mobility/arel/visitor.rb +0 -61
  49. data/lib/mobility/sequel/column_changes.rb +0 -28
  50. data/lib/mobility/sequel/hash_initializer.rb +0 -21
  51. data/lib/mobility/sequel/model_translation.rb +0 -20
  52. data/lib/mobility/sequel/sql.rb +0 -16
  53. data/lib/mobility/sequel/string_translation.rb +0 -10
  54. data/lib/mobility/sequel/text_translation.rb +0 -10
  55. data/lib/mobility/sequel/translation.rb +0 -53
@@ -15,6 +15,7 @@ attributes only.
15
15
  extend Plugin
16
16
 
17
17
  default true
18
+ requires :attributes
18
19
 
19
20
  initialize_hook do |*names|
20
21
  include InstanceMethods
@@ -32,8 +32,15 @@ for aggregating attributes.
32
32
  end
33
33
 
34
34
  included_hook do |klass|
35
- klass.extend ClassMethods
36
- @names.each { |name| klass.register_mobility_attribute(name) }
35
+ names = @names
36
+
37
+ klass.class_eval do
38
+ extend ClassMethods
39
+ names.each { |name| mobility_attributes << name.to_s }
40
+ mobility_attributes.uniq!
41
+ rescue FrozenError
42
+ raise FrozenAttributesError, "Attempting to translate these attributes on #{klass}, which has already been subclassed: #{names.join(', ')}."
43
+ end
37
44
  end
38
45
 
39
46
  module ClassMethods
@@ -44,25 +51,20 @@ for aggregating attributes.
44
51
  mobility_attributes.include?(name.to_s)
45
52
  end
46
53
 
47
- # Register a new attribute name. Public, but treat as internal.
48
- # @param [String, Symbol] Attribute name
49
- def register_mobility_attribute(name)
50
- (self.mobility_attributes << name.to_s).uniq!
51
- end
52
-
53
- def inherited(klass)
54
- super
55
- mobility_attributes.each { |name| klass.register_mobility_attribute(name) }
56
- end
57
-
58
- protected
59
-
60
54
  # Return translated attribute names on this model.
61
55
  # @return [Array<String>] Attribute names
62
56
  def mobility_attributes
63
57
  @mobility_attributes ||= []
64
58
  end
59
+
60
+ def inherited(klass)
61
+ super
62
+ attrs = mobility_attributes.freeze # ensure attributes are not modified after being inherited
63
+ klass.class_eval { @mobility_attributes = attrs.dup }
64
+ end
65
65
  end
66
+
67
+ class FrozenAttributesError < Error; end
66
68
  end
67
69
 
68
70
  register_plugin(:attributes, Attributes)
@@ -56,8 +56,11 @@ Defines:
56
56
 
57
57
  backend_class.setup_model(klass, names)
58
58
 
59
- @names.each do |name|
60
- klass.register_mobility_backend_class(name, @backend_class)
59
+ names = @names
60
+ backend_class = @backend_class
61
+
62
+ klass.class_eval do
63
+ names.each { |name| mobility_backend_classes[name.to_sym] = backend_class }
61
64
  end
62
65
 
63
66
  backend_class
@@ -137,12 +140,9 @@ Defines:
137
140
  raise KeyError, "No backend for: #{name}"
138
141
  end
139
142
 
140
- def register_mobility_backend_class(name, backend_class)
141
- mobility_backend_classes[name.to_sym] = backend_class
142
- end
143
-
144
143
  def inherited(klass)
145
- klass.mobility_backend_classes.merge!(@mobility_backend_classes)
144
+ parent_classes = mobility_backend_classes.freeze # ensure backend classes are not modified after being inherited
145
+ klass.class_eval { @mobility_backend_classes = parent_classes.dup }
146
146
  super
147
147
  end
148
148
 
@@ -51,7 +51,7 @@ Automatically includes dirty plugin in model class when enabled.
51
51
  # @!group Backend Accessors
52
52
  # @!macro backend_writer
53
53
  # @param [Hash] options
54
- def write(locale, value, options = {})
54
+ def write(locale, value, **options)
55
55
  locale_accessor = Mobility.normalize_locale_accessor(attribute, locale).to_sym
56
56
  if model.column_changes.has_key?(locale_accessor) && model.initial_values[locale_accessor] == value
57
57
  super
@@ -8,8 +8,8 @@ module Mobility
8
8
  module VERSION
9
9
  MAJOR = 1
10
10
  MINOR = 0
11
- TINY = 0
12
- PRE = "beta1"
11
+ TINY = 2
12
+ PRE = nil
13
13
 
14
14
  STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".")
15
15
  end
@@ -1,5 +1,4 @@
1
1
  class CreateStringTranslations < <%= activerecord_migration_class %>
2
-
3
2
  def change
4
3
  create_table :mobility_string_translations do |t|
5
4
  t.string :locale, null: false
@@ -1,5 +1,4 @@
1
1
  class CreateTextTranslations < <%= activerecord_migration_class %>
2
-
3
2
  def change
4
3
  create_table :mobility_text_translations do |t|
5
4
  t.string :locale, null: false
@@ -1,5 +1,4 @@
1
1
  Mobility.configure do
2
-
3
2
  # PLUGINS
4
3
  plugins do
5
4
  # Backend
@@ -104,5 +103,14 @@ Mobility.configure do
104
103
  #
105
104
  # Or define specific defaults by uncommenting line below
106
105
  # locale_accessors [:en, :ja]
106
+
107
+ # Attribute Methods
108
+ #
109
+ # Adds translated attributes to +attributes+ hash, and defines methods
110
+ # +translated_attributes+ and +untranslated_attributes+ which return hashes
111
+ # with translated and untranslated attributes, respectively. Be aware that
112
+ # this plugin can create conflicts with other gems.
113
+ #
114
+ # attribute_methods
107
115
  end
108
116
  end
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: 1.0.0.beta1
4
+ version: 1.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chris Salzberg
@@ -34,7 +34,7 @@ cert_chain:
34
34
  gSQml7TqcC6dZRsZRwYqzD9kUwdAJoCqno2CBUKs2l0yQAjFT36lRrVJznb7uWwa
35
35
  xpPFnsrtyaZW6Dty8TSG3qzmeGpmpIotA8x1VA==
36
36
  -----END CERTIFICATE-----
37
- date: 2020-11-03 00:00:00.000000000 Z
37
+ date: 2021-01-24 00:00:00.000000000 Z
38
38
  dependencies:
39
39
  - !ruby/object:Gem::Dependency
40
40
  name: request_store
@@ -156,14 +156,6 @@ files:
156
156
  - README.md
157
157
  - Rakefile
158
158
  - lib/mobility.rb
159
- - lib/mobility/active_record/model_translation.rb
160
- - lib/mobility/active_record/string_translation.rb
161
- - lib/mobility/active_record/text_translation.rb
162
- - lib/mobility/active_record/translation.rb
163
- - lib/mobility/arel.rb
164
- - lib/mobility/arel/nodes.rb
165
- - lib/mobility/arel/nodes/pg_ops.rb
166
- - lib/mobility/arel/visitor.rb
167
159
  - lib/mobility/backend.rb
168
160
  - lib/mobility/backends.rb
169
161
  - lib/mobility/backends/active_record.rb
@@ -209,6 +201,9 @@ files:
209
201
  - lib/mobility/plugins/active_record/dirty.rb
210
202
  - lib/mobility/plugins/active_record/query.rb
211
203
  - lib/mobility/plugins/active_record/uniqueness_validation.rb
204
+ - lib/mobility/plugins/arel.rb
205
+ - lib/mobility/plugins/arel/nodes.rb
206
+ - lib/mobility/plugins/arel/nodes/pg_ops.rb
212
207
  - lib/mobility/plugins/attribute_methods.rb
213
208
  - lib/mobility/plugins/attributes.rb
214
209
  - lib/mobility/plugins/backend.rb
@@ -228,13 +223,6 @@ files:
228
223
  - lib/mobility/plugins/sequel/dirty.rb
229
224
  - lib/mobility/plugins/sequel/query.rb
230
225
  - lib/mobility/plugins/writer.rb
231
- - lib/mobility/sequel/column_changes.rb
232
- - lib/mobility/sequel/hash_initializer.rb
233
- - lib/mobility/sequel/model_translation.rb
234
- - lib/mobility/sequel/sql.rb
235
- - lib/mobility/sequel/string_translation.rb
236
- - lib/mobility/sequel/text_translation.rb
237
- - lib/mobility/sequel/translation.rb
238
226
  - lib/mobility/translations.rb
239
227
  - lib/mobility/util.rb
240
228
  - lib/mobility/version.rb
@@ -259,7 +247,13 @@ metadata:
259
247
  homepage_uri: https://github.com/shioyama/mobility
260
248
  source_code_uri: https://github.com/shioyama/mobility
261
249
  changelog_uri: https://github.com/shioyama/mobility/blob/master/CHANGELOG.md
262
- post_install_message:
250
+ post_install_message: |2
251
+
252
+ Warning: Mobility v1.0 includes backwards-incompatible changes (mostly around configuration).
253
+
254
+ If you are upgrading from an earlier version, please see:
255
+ - https://github.com/shioyama/mobility/releases/tag/v1.0.0
256
+ - https://github.com/shioyama/mobility/wiki/Introduction-to-Mobility-v1.0
263
257
  rdoc_options: []
264
258
  require_paths:
265
259
  - lib
@@ -270,9 +264,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
270
264
  version: '2.5'
271
265
  required_rubygems_version: !ruby/object:Gem::Requirement
272
266
  requirements:
273
- - - ">"
267
+ - - ">="
274
268
  - !ruby/object:Gem::Version
275
- version: 1.3.1
269
+ version: '0'
276
270
  requirements: []
277
271
  rubygems_version: 3.1.2
278
272
  signing_key:
metadata.gz.sig CHANGED
Binary file
@@ -1,14 +0,0 @@
1
- module Mobility
2
- module ActiveRecord
3
- =begin
4
-
5
- Subclassed dynamically to generate translation class in
6
- {Backends::ActiveRecord::Table} backend.
7
-
8
- =end
9
- class ModelTranslation < ::ActiveRecord::Base
10
- self.abstract_class = true
11
- validates :locale, presence: true
12
- end
13
- end
14
- end
@@ -1,10 +0,0 @@
1
- # frozen_string_literal: true
2
- require "mobility/active_record/translation"
3
-
4
- module Mobility
5
- module ActiveRecord
6
- class StringTranslation < Translation
7
- self.table_name = "mobility_string_translations"
8
- end
9
- end
10
- end
@@ -1,10 +0,0 @@
1
- # frozen_string_literal: true
2
- require "mobility/active_record/translation"
3
-
4
- module Mobility
5
- module ActiveRecord
6
- class TextTranslation < Translation
7
- self.table_name = "mobility_text_translations"
8
- end
9
- end
10
- end
@@ -1,14 +0,0 @@
1
- module Mobility
2
- module ActiveRecord
3
- # @abstract Subclass and set +table_name+ to implement for a particular column type.
4
- class Translation < ::ActiveRecord::Base
5
- self.abstract_class = true
6
-
7
- belongs_to :translatable, polymorphic: true, touch: true
8
-
9
- validates :key, presence: true, uniqueness: { scope: [:translatable_id, :translatable_type, :locale], case_sensitive: true }
10
- validates :translatable, presence: true
11
- validates :locale, presence: true
12
- end
13
- end
14
- end
@@ -1,49 +0,0 @@
1
- # frozen-string-literal: true
2
- require "mobility/arel/nodes"
3
- require "mobility/arel/visitor"
4
-
5
- module Mobility
6
- module Arel
7
- module MobilityExpressions
8
- include ::Arel::Expressions
9
-
10
- # @note This is necessary in order to ensure that when a translated
11
- # attribute is selected with an alias using +AS+, the resulting
12
- # expression can still be counted without blowing up.
13
- #
14
- # Extending +::Arel::Expressions+ is necessary to convince ActiveRecord
15
- # that this node should not be stringified, which otherwise would
16
- # result in garbage SQL.
17
- #
18
- # @see https://github.com/rails/rails/blob/847342c25c61acaea988430dc3ab66a82e3ed486/activerecord/lib/active_record/relation/calculations.rb#L261
19
- def as(*)
20
- super
21
- .extend(::Arel::Expressions)
22
- .extend(Countable)
23
- end
24
-
25
- module Countable
26
- # @note This allows expressions with selected translated attributes to
27
- # be counted.
28
- def count(*args)
29
- left.count(*args)
30
- end
31
- end
32
- end
33
-
34
- class Attribute < ::Arel::Attributes::Attribute
35
- include MobilityExpressions
36
-
37
- attr_reader :backend_class
38
- attr_reader :locale
39
- attr_reader :attribute_name
40
-
41
- def initialize(relation, column_name, locale, backend_class, attribute_name = nil)
42
- @backend_class = backend_class
43
- @locale = locale
44
- @attribute_name = attribute_name || column_name
45
- super(relation, column_name)
46
- end
47
- end
48
- end
49
- end
@@ -1,13 +0,0 @@
1
- # frozen-string-literal: true
2
- module Mobility
3
- module Arel
4
- module Nodes
5
- class Binary < ::Arel::Nodes::Binary; end
6
- class Grouping < ::Arel::Nodes::Grouping; end
7
-
8
- ::Arel::Visitors::ToSql.class_eval do
9
- alias :visit_Mobility_Arel_Nodes_Grouping :visit_Arel_Nodes_Grouping
10
- end
11
- end
12
- end
13
- end
@@ -1,132 +0,0 @@
1
- # frozen-string-literal: true
2
- require "mobility/arel"
3
-
4
- module Mobility
5
- module Arel
6
- module Nodes
7
- %w[
8
- JsonDashArrow
9
- JsonDashDoubleArrow
10
- JsonbDashArrow
11
- JsonbDashDoubleArrow
12
- JsonbQuestion
13
- HstoreDashArrow
14
- HstoreQuestion
15
- ].each do |name|
16
- const_set name, (Class.new(Binary) do
17
- include ::Arel::Predications
18
- include ::Arel::OrderPredications
19
- include ::Arel::AliasPredication
20
- include ::Mobility::Arel::MobilityExpressions
21
-
22
- def lower
23
- super self
24
- end
25
- end)
26
- end
27
-
28
- # Needed for AR 4.2, can be removed when support is deprecated
29
- if ::ActiveRecord::VERSION::STRING < '5.0'
30
- [JsonbDashDoubleArrow, HstoreDashArrow].each do |klass|
31
- klass.class_eval do
32
- def quoted_node other
33
- other && super
34
- end
35
- end
36
- end
37
- end
38
-
39
- class Jsonb < JsonbDashDoubleArrow
40
- def to_dash_arrow
41
- JsonbDashArrow.new left, right
42
- end
43
-
44
- def to_question
45
- JsonbQuestion.new left, right
46
- end
47
-
48
- def eq other
49
- case other
50
- when NilClass
51
- to_question.not
52
- when Integer, Array, ::Hash
53
- to_dash_arrow.eq other.to_json
54
- when Jsonb
55
- to_dash_arrow.eq other.to_dash_arrow
56
- when JsonbDashArrow
57
- to_dash_arrow.eq other
58
- else
59
- super
60
- end
61
- end
62
- end
63
-
64
- class Hstore < HstoreDashArrow
65
- def to_question
66
- HstoreQuestion.new left, right
67
- end
68
-
69
- def eq other
70
- other.nil? ? to_question.not : super
71
- end
72
- end
73
-
74
- class Json < JsonDashDoubleArrow; end
75
-
76
- class JsonContainer < Json
77
- def initialize column, locale, attr
78
- super(Arel::Nodes::JsonDashArrow.new(column, locale), attr)
79
- end
80
- end
81
-
82
- class JsonbContainer < Jsonb
83
- def initialize column, locale, attr
84
- @column, @locale = column, locale
85
- super(JsonbDashArrow.new(column, locale), attr)
86
- end
87
-
88
- def eq other
89
- other.nil? ? super.or(JsonbQuestion.new(@column, @locale).not) : super
90
- end
91
- end
92
- end
93
-
94
- module Visitors
95
- def visit_Mobility_Arel_Nodes_JsonDashArrow o, a
96
- json_infix o, a, '->'
97
- end
98
-
99
- def visit_Mobility_Arel_Nodes_JsonDashDoubleArrow o, a
100
- json_infix o, a, '->>'
101
- end
102
-
103
- def visit_Mobility_Arel_Nodes_JsonbDashArrow o, a
104
- json_infix o, a, '->'
105
- end
106
-
107
- def visit_Mobility_Arel_Nodes_JsonbDashDoubleArrow o, a
108
- json_infix o, a, '->>'
109
- end
110
-
111
- def visit_Mobility_Arel_Nodes_JsonbQuestion o, a
112
- json_infix o, a, '?'
113
- end
114
-
115
- def visit_Mobility_Arel_Nodes_HstoreDashArrow o, a
116
- json_infix o, a, '->'
117
- end
118
-
119
- def visit_Mobility_Arel_Nodes_HstoreQuestion o, a
120
- json_infix o, a, '?'
121
- end
122
-
123
- private
124
-
125
- def json_infix o, a, opr
126
- visit(Nodes::Grouping.new(::Arel::Nodes::InfixOperation.new(opr, o.left, o.right)), a)
127
- end
128
- end
129
-
130
- ::Arel::Visitors::PostgreSQL.include Visitors
131
- end
132
- end