mobility 1.0.0.beta2 → 1.0.0.rc1

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 (46) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +3 -2
  3. data.tar.gz.sig +0 -0
  4. data/CHANGELOG.md +5 -0
  5. data/Gemfile.lock +19 -0
  6. data/README.md +4 -4
  7. data/lib/mobility.rb +60 -6
  8. data/lib/mobility/backends/active_record.rb +1 -1
  9. data/lib/mobility/backends/active_record/column.rb +1 -1
  10. data/lib/mobility/backends/active_record/container.rb +4 -4
  11. data/lib/mobility/backends/active_record/hstore.rb +3 -3
  12. data/lib/mobility/backends/active_record/json.rb +3 -3
  13. data/lib/mobility/backends/active_record/jsonb.rb +3 -3
  14. data/lib/mobility/backends/active_record/key_value.rb +27 -11
  15. data/lib/mobility/backends/active_record/table.rb +11 -6
  16. data/lib/mobility/backends/sequel.rb +32 -0
  17. data/lib/mobility/backends/sequel/container.rb +5 -3
  18. data/lib/mobility/backends/sequel/key_value.rb +79 -12
  19. data/lib/mobility/backends/sequel/pg_hash.rb +6 -6
  20. data/lib/mobility/backends/sequel/table.rb +18 -8
  21. data/lib/mobility/backends/table.rb +11 -6
  22. data/lib/mobility/plugins/active_record.rb +3 -0
  23. data/lib/mobility/plugins/active_record/backend.rb +2 -0
  24. data/lib/mobility/plugins/active_record/query.rb +2 -2
  25. data/lib/mobility/plugins/arel.rb +125 -0
  26. data/lib/mobility/plugins/arel/nodes.rb +15 -0
  27. data/lib/mobility/plugins/arel/nodes/pg_ops.rb +134 -0
  28. data/lib/mobility/plugins/sequel/dirty.rb +1 -1
  29. data/lib/mobility/version.rb +1 -1
  30. metadata +5 -17
  31. metadata.gz.sig +0 -0
  32. data/lib/mobility/active_record/model_translation.rb +0 -14
  33. data/lib/mobility/active_record/string_translation.rb +0 -10
  34. data/lib/mobility/active_record/text_translation.rb +0 -10
  35. data/lib/mobility/active_record/translation.rb +0 -14
  36. data/lib/mobility/arel.rb +0 -49
  37. data/lib/mobility/arel/nodes.rb +0 -13
  38. data/lib/mobility/arel/nodes/pg_ops.rb +0 -132
  39. data/lib/mobility/arel/visitor.rb +0 -61
  40. data/lib/mobility/sequel/column_changes.rb +0 -28
  41. data/lib/mobility/sequel/hash_initializer.rb +0 -21
  42. data/lib/mobility/sequel/model_translation.rb +0 -20
  43. data/lib/mobility/sequel/sql.rb +0 -16
  44. data/lib/mobility/sequel/string_translation.rb +0 -10
  45. data/lib/mobility/sequel/text_translation.rb +0 -10
  46. data/lib/mobility/sequel/translation.rb +0 -53
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2346e4ef46985b520c5feea3577a6644f213e1fe89e3dfd5960f3347c72a1134
4
- data.tar.gz: df38726f94dca7139a3eb9cf838b27dfede5378c34290a5298e7dcde01bf3c90
3
+ metadata.gz: 8658079d8c9fad02763385921421140d2410cde1d505c286627de5a8c1819612
4
+ data.tar.gz: 9bb012a9f564971e0c24fd3015e20e17384d7cbd77f2f0a5f1f1505e5262277a
5
5
  SHA512:
6
- metadata.gz: 236ad0894645f98bf2a21c6848b4ba439da84b24862a56f6fca878889a6cd9a79108711923961d2f9ee75b6a6ee8482fcefff213b5433736fa507332db0cc253
7
- data.tar.gz: a3e78f97d08d26e18ac8187b961097e686c3fc5650f45ae84fb4aa1aad1ccd0970410f2b9e887d8618ed6c1a09e559b1fe3fd0428df591de011961a0c2da1379
6
+ metadata.gz: 0a4a8a38a27d6f727091062010087466c85bfe48ce369395adb5501bd9875cfba21a56bce6a13b92b5cf83746883934f4161835f1336adedd9539bbf1138c51b
7
+ data.tar.gz: ca65fdaf7af558d235fdb5ba45347b9ca2319d9e6d69ddf7611afa2a50a477a30998316ce8661ca640ced1d09cd05f6ff282b1edfebd79abf4830c142bdf95df
@@ -1,2 +1,3 @@
1
- ��[�c�$��=����K��N����-��R��6�VA����(�h Zu�j�;~�6�vL�vT3Ԃ�lc� P�:�2�{�Ie1�מ9�v��g�|�+9�ov#�ƆL��7�F�7��b���ϔ�![j{̖�jdF�wWr���K���4ۿZb !��w*�2̂��SV�}�������1�W(�S�;-�+��7�
2
- i��㜘~ '�5t6��в����Q��Oд�K�`�NK3����~� ���
1
+ 8��>
2
+ i!�]>T*Ho�m꿻��󒁹h�^B���"@�y ��1�$�{�{�Uq�K��Cu1+7)�&y��/z���b�-�ޮ�]vR��^�.'$~��btam��b�}F@\?
3
+ �Օ�F?#�D�-��*�^�M�ɼ�̨��{�~��la�eY�f7 }o�<������Mye,H^��o@�^~ۦE�V0���aD��u���
data.tar.gz.sig CHANGED
Binary file
@@ -4,6 +4,11 @@
4
4
 
5
5
  1.0 is a rewrite of many internals of the gem. Please see the [wiki page on v1.0](https://github.com/shioyama/mobility/wiki/Introduction-to-Mobility-v1.0) for more details on how to upgrade.
6
6
 
7
+ ## 1.0.0.rc1 (pre-release)
8
+
9
+ - Remove `Mobility::ActiveRecord`, `Mobility::Sequel` and `Mobility::Arel`, and
10
+ general cleanup ([#464](https://github.com/shioyama/mobility/pull/464))
11
+
7
12
  ## 1.0.0.beta2 (pre-release)
8
13
 
9
14
  - Refactor attributes & backend plugins and make `mobility_attributes` public
@@ -8,6 +8,17 @@ PATH
8
8
  GEM
9
9
  remote: https://rubygems.org/
10
10
  specs:
11
+ activemodel (6.0.3.4)
12
+ activesupport (= 6.0.3.4)
13
+ activerecord (6.0.3.4)
14
+ activemodel (= 6.0.3.4)
15
+ activesupport (= 6.0.3.4)
16
+ activesupport (6.0.3.4)
17
+ concurrent-ruby (~> 1.0, >= 1.0.2)
18
+ i18n (>= 0.7, < 2)
19
+ minitest (~> 5.1)
20
+ tzinfo (~> 1.1)
21
+ zeitwerk (~> 2.2, >= 2.2.2)
11
22
  benchmark-ips (2.8.3)
12
23
  byebug (11.1.3)
13
24
  coderay (1.1.3)
@@ -37,10 +48,12 @@ GEM
37
48
  rb-inotify (~> 0.9, >= 0.9.10)
38
49
  lumberjack (1.2.8)
39
50
  method_source (1.0.0)
51
+ minitest (5.14.2)
40
52
  nenv (0.3.0)
41
53
  notiffany (0.1.3)
42
54
  nenv (~> 0.1)
43
55
  shellany (~> 0.0)
56
+ pg (1.2.3)
44
57
  pry (0.13.1)
45
58
  coderay (~> 1.1)
46
59
  method_source (~> 1.0)
@@ -69,16 +82,22 @@ GEM
69
82
  rspec-support (3.10.0)
70
83
  shellany (0.0.1)
71
84
  thor (1.0.1)
85
+ thread_safe (0.3.6)
86
+ tzinfo (1.2.8)
87
+ thread_safe (~> 0.1)
72
88
  yard (0.9.25)
89
+ zeitwerk (2.4.1)
73
90
 
74
91
  PLATFORMS
75
92
  ruby
76
93
 
77
94
  DEPENDENCIES
95
+ activerecord (>= 6.0.0, < 6.1)
78
96
  benchmark-ips
79
97
  database_cleaner (~> 1.5, >= 1.5.3)
80
98
  guard-rspec
81
99
  mobility!
100
+ pg
82
101
  pry-byebug
83
102
  rake (~> 12, >= 12.2.1)
84
103
  rspec (~> 3.0)
data/README.md CHANGED
@@ -13,7 +13,7 @@ Mobility
13
13
  [wiki]: https://github.com/shioyama/mobility/wiki
14
14
 
15
15
  **This is the readme for the [`master`](https://github.com/shioyama/mobility)
16
- branch, which corresponds to v1.0.0.beta, a pre-release version of Mobility.
16
+ branch, which corresponds to v1.0.0.rc1, a pre-release version of Mobility.
17
17
  If you are using an earlier version (0.8.x or earlier), you probably want the
18
18
  readme on the [0-8-stable
19
19
  branch](https://github.com/shioyama/mobility/tree/0-8-stable).**
@@ -58,7 +58,7 @@ To use the latest pre-version of Mobility 1.0, add this line to your
58
58
  application's Gemfile:
59
59
 
60
60
  ```ruby
61
- gem 'mobility', '~> 1.0.0.beta2'
61
+ gem 'mobility', '~> 1.0.0.rc1'
62
62
  ```
63
63
 
64
64
  For the latest stable version of Mobility, see the readme on the
@@ -91,10 +91,10 @@ The generator will create an initializer file `config/initializers/mobility.rb`
91
91
  which looks something like this:
92
92
 
93
93
  ```ruby
94
- Mobility.configure do |config|
94
+ Mobility.configure do
95
95
  # PLUGINS
96
96
 
97
- config.plugins do
97
+ plugins do
98
98
  backend :key_value
99
99
 
100
100
  active_record
@@ -6,17 +6,71 @@ require 'mobility/version'
6
6
  =begin
7
7
 
8
8
  Mobility is a gem for storing and retrieving localized data through attributes
9
- on a class. The {Mobility} module includes all necessary methods and modules to
10
- support defining backend accessors on a class.
9
+ on a class.
11
10
 
12
- To enable Mobility on a class, simply include or extend the {Mobility} module,
13
- and define any attribute accessors using {Translates#translates}.
11
+ There are two ways to translate attributes on a class, both of which are
12
+ variations on the same basic mechanism. The first and most common way is to
13
+ extend the `Mobility` module, which adds a class method +translates+.
14
+ Translated attributes can then be defined like this:
14
15
 
15
- class MyClass
16
+ class Post
16
17
  extend Mobility
17
18
  translates :title, backend: :key_value
18
19
  end
19
20
 
21
+ Behind the scenes, +translates+ simply creates an instance of
22
+ +Mobility.translations_class+, passes it whatever arguments are passed to
23
+ +translates+, and includes the instance (which is a module) into the class.
24
+
25
+ So the above example is equivalent to:
26
+
27
+ class Post
28
+ Mobility.translations_class.new(:title, backend: :key_value)
29
+ end
30
+
31
+ `Mobility.translations_class` is a subclass of `Mobility::Translations` created
32
+ when `Mobility.configure` is called to configure Mobility. In fact, when you
33
+ call `Mobility.configure`, it is the subclass of `Mobility::Translations` which
34
+ is passed to the block as `config`. Plugins and plugin configuration is all
35
+ applied to the same `Mobility.translations_class`.
36
+
37
+ There is another way to use Mobility, which is to create your own subclass or
38
+ subclasses of +Mobility::Translations+ and include them explicitly, without
39
+ using +translates+.
40
+
41
+ For example:
42
+
43
+ class Translations < Mobility::Translations
44
+ plugins do
45
+ backend :key_value
46
+ # ...
47
+ end
48
+ end
49
+
50
+ class Post
51
+ include Translations.new(:title)
52
+ end
53
+
54
+ This usage might be handy if, for example, you want to have more complex
55
+ configuration, where some models use some plugins while others do not. Since
56
+ `Mobility::Translations` is a class like any other, you can subclass it and
57
+ define plugins specifically on the subclass which are not present on its
58
+ parent:
59
+
60
+ class TranslationsWithFallbacks < Translations
61
+ plugins do
62
+ fallbacks
63
+ end
64
+ end
65
+
66
+ class Comment
67
+ include TranslationsWithFallbacks.new(:author)
68
+ end
69
+
70
+ In this case, +Comment+ uses +TranslationsWithFallbacks+ and thus has the
71
+ fallbacks plugin, whereas +Post+ uses +Translations+ which does not have that
72
+ plugin enabled.
73
+
20
74
  =end
21
75
  module Mobility
22
76
  # A generic exception used by Mobility.
@@ -50,6 +104,7 @@ module Mobility
50
104
  model_class.extend self
51
105
  end
52
106
 
107
+ # Alias to default backend defined on *translations_class+.
53
108
  # @return [Symbol,Class]
54
109
  def default_backend
55
110
  translations_class.defaults[:backend]
@@ -65,7 +120,6 @@ module Mobility
65
120
  yield translations_class
66
121
  end
67
122
  end
68
- # @!endgroup
69
123
 
70
124
  def translates_with(pluggable)
71
125
  raise ArgumentError, "translations class must be a subclass of Module." unless Module === pluggable
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
  require "mobility/backend"
3
- require "mobility/arel"
3
+ require "mobility/plugins/arel"
4
4
 
5
5
  module Mobility
6
6
  module Backends
@@ -57,7 +57,7 @@ can be run again to add new attributes or locales.)
57
57
  # on model table
58
58
  def self.build_node(attr, locale)
59
59
  model_class.arel_table[Column.column_name_for(attr, locale)]
60
- .extend(::Mobility::Arel::MobilityExpressions)
60
+ .extend(Plugins::Arel::MobilityExpressions)
61
61
  end
62
62
 
63
63
  private
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
  require "mobility/backends/active_record"
3
3
  require "mobility/backends/container"
4
- require "mobility/arel/nodes/pg_ops"
4
+ require "mobility/plugins/arel/nodes/pg_ops"
5
5
 
6
6
  module Mobility
7
7
  module Backends
@@ -49,15 +49,15 @@ Implements the {Mobility::Backends::Container} backend for ActiveRecord models.
49
49
 
50
50
  # @param [String] attr Attribute name
51
51
  # @param [Symbol] locale Locale
52
- # @return [Mobility::Arel::Nodes::Json,Mobility::Arel::Nodes::Jsonb] Arel
52
+ # @return [Mobility::Plugins::Arel::Nodes::Json,Mobility::Arel::Nodes::Jsonb] Arel
53
53
  # node for attribute on json or jsonb column
54
54
  def build_node(attr, locale)
55
55
  column = model_class.arel_table[column_name]
56
56
  case column_type
57
57
  when :json
58
- Arel::Nodes::JsonContainer.new(column, build_quoted(locale), build_quoted(attr))
58
+ Plugins::Arel::Nodes::JsonContainer.new(column, build_quoted(locale), build_quoted(attr))
59
59
  when :jsonb
60
- Arel::Nodes::JsonbContainer.new(column, build_quoted(locale), build_quoted(attr))
60
+ Plugins::Arel::Nodes::JsonbContainer.new(column, build_quoted(locale), build_quoted(attr))
61
61
  end
62
62
  end
63
63
 
@@ -1,5 +1,5 @@
1
1
  require 'mobility/backends/active_record/pg_hash'
2
- require 'mobility/arel/nodes/pg_ops'
2
+ require 'mobility/plugins/arel/nodes/pg_ops'
3
3
 
4
4
  module Mobility
5
5
  module Backends
@@ -24,11 +24,11 @@ Implements the {Mobility::Backends::Hstore} backend for ActiveRecord models.
24
24
 
25
25
  # @param [String] attr Attribute name
26
26
  # @param [Symbol] locale Locale
27
- # @return [Mobility::Arel::Nodes::Hstore] Arel node for value of
27
+ # @return [Mobility::Plugins::Arel::Nodes::Hstore] Arel node for value of
28
28
  # attribute key on hstore column
29
29
  def self.build_node(attr, locale)
30
30
  column_name = column_affix % attr
31
- Arel::Nodes::Hstore.new(model_class.arel_table[column_name], build_quoted(locale))
31
+ Plugins::Arel::Nodes::Hstore.new(model_class.arel_table[column_name], build_quoted(locale))
32
32
  end
33
33
  end
34
34
  end
@@ -1,5 +1,5 @@
1
1
  require 'mobility/backends/active_record/pg_hash'
2
- require 'mobility/arel/nodes/pg_ops'
2
+ require 'mobility/plugins/arel/nodes/pg_ops'
3
3
 
4
4
  module Mobility
5
5
  module Backends
@@ -32,11 +32,11 @@ Implements the {Mobility::Backends::Json} backend for ActiveRecord models.
32
32
 
33
33
  # @param [String] attr Attribute name
34
34
  # @param [Symbol] locale Locale
35
- # @return [Mobility::Arel::Nodes::Json] Arel node for value of
35
+ # @return [Mobility::Plugins::Arel::Nodes::Json] Arel node for value of
36
36
  # attribute key on jsonb column
37
37
  def self.build_node(attr, locale)
38
38
  column_name = column_affix % attr
39
- Arel::Nodes::Json.new(model_class.arel_table[column_name], build_quoted(locale))
39
+ Plugins::Arel::Nodes::Json.new(model_class.arel_table[column_name], build_quoted(locale))
40
40
  end
41
41
  end
42
42
  end
@@ -1,5 +1,5 @@
1
1
  require 'mobility/backends/active_record/pg_hash'
2
- require 'mobility/arel/nodes/pg_ops'
2
+ require 'mobility/plugins/arel/nodes/pg_ops'
3
3
 
4
4
  module Mobility
5
5
  module Backends
@@ -32,11 +32,11 @@ Implements the {Mobility::Backends::Jsonb} backend for ActiveRecord models.
32
32
 
33
33
  # @param [String] attr Attribute name
34
34
  # @param [Symbol] locale Locale
35
- # @return [Mobility::Arel::Nodes::Jsonb] Arel node for value of
35
+ # @return [Mobility::Plugins::Arel::Nodes::Jsonb] Arel node for value of
36
36
  # attribute key on jsonb column
37
37
  def self.build_node(attr, locale)
38
38
  column_name = column_affix % attr
39
- Arel::Nodes::Jsonb.new(model_class.arel_table[column_name], build_quoted(locale))
39
+ Plugins::Arel::Nodes::Jsonb.new(model_class.arel_table[column_name], build_quoted(locale))
40
40
  end
41
41
  end
42
42
  end
@@ -1,8 +1,6 @@
1
1
  # frozen-string-literal: true
2
2
  require "mobility/backends/active_record"
3
3
  require "mobility/backends/key_value"
4
- require "mobility/active_record/string_translation"
5
- require "mobility/active_record/text_translation"
6
4
 
7
5
  module Mobility
8
6
  module Backends
@@ -37,21 +35,21 @@ Implements the {Mobility::Backends::KeyValue} backend for ActiveRecord models.
37
35
  super
38
36
  if type = options[:type]
39
37
  options[:association_name] ||= :"#{options[:type]}_translations"
40
- options[:class_name] ||= Mobility::ActiveRecord.const_get("#{type.capitalize}Translation")
38
+ options[:class_name] ||= const_get("#{type.capitalize}Translation")
41
39
  end
42
40
  options[:table_alias_affix] = "#{model_class}_%s_#{options[:association_name]}"
43
41
  rescue NameError
44
- raise ArgumentError, "You must define a Mobility::ActiveRecord::#{type.capitalize}Translation class."
42
+ raise ArgumentError, "You must define a Mobility::Backends::ActiveRecord::KeyValue::#{type.capitalize}Translation class."
45
43
  end
46
44
  # @!endgroup
47
45
 
48
46
  # @param [String] attr Attribute name
49
47
  # @param [Symbol] _locale Locale
50
- # @return [Mobility::Arel::Attribute] Arel attribute for aliased
48
+ # @return [Mobility::Plugins::Arel::Attribute] Arel attribute for aliased
51
49
  # translation table value column
52
50
  def build_node(attr, locale)
53
51
  aliased_table = class_name.arel_table.alias(table_alias(attr, locale))
54
- Arel::Attribute.new(aliased_table, :value, locale, self, attr.to_sym)
52
+ Plugins::Arel::Attribute.new(aliased_table, :value, locale, self, attr.to_sym)
55
53
  end
56
54
 
57
55
  # Joins translations using either INNER/OUTER join appropriate to the query.
@@ -119,7 +117,7 @@ Implements the {Mobility::Backends::KeyValue} backend for ActiveRecord models.
119
117
  # The title predicate has a non-nil value, so we can use an INNER JOIN,
120
118
  # whereas we are searching for nil content, which requires an OUTER JOIN.
121
119
  #
122
- class Visitor < ::Mobility::Arel::Visitor
120
+ class Visitor < Plugins::Arel::Visitor
123
121
  private
124
122
 
125
123
  def visit_Arel_Nodes_Equality(object)
@@ -141,7 +139,7 @@ Implements the {Mobility::Backends::KeyValue} backend for ActiveRecord models.
141
139
  transform_values { OUTER_JOIN }
142
140
  end
143
141
 
144
- def visit_Mobility_Arel_Attribute(object)
142
+ def visit_Mobility_Plugins_Arel_Attribute(object)
145
143
  if object.backend_class == backend_class && object.locale == locale
146
144
  { object.attribute_name => OUTER_JOIN }
147
145
  end
@@ -194,8 +192,8 @@ Implements the {Mobility::Backends::KeyValue} backend for ActiveRecord models.
194
192
 
195
193
  # Returns translation for a given locale, or builds one if none is present.
196
194
  # @param [Symbol] locale
197
- # @return [Mobility::ActiveRecord::TextTranslation,Mobility::ActiveRecord::StringTranslation]
198
- def translation_for(locale, _options = {})
195
+ # @return [Mobility::Backends::ActiveRecord::KeyValue::TextTranslation,Mobility::Backends::ActiveRecord::KeyValue::StringTranslation]
196
+ def translation_for(locale, **)
199
197
  translation = translations.find { |t| t.key == attribute && t.locale == locale.to_s }
200
198
  translation ||= translations.build(locale: locale, key: attribute)
201
199
  translation
@@ -205,12 +203,30 @@ Implements the {Mobility::Backends::KeyValue} backend for ActiveRecord models.
205
203
  def self.included(model_class)
206
204
  model_class.after_destroy do
207
205
  [:string, :text].each do |type|
208
- Mobility::ActiveRecord.const_get("#{type.capitalize}Translation").
206
+ Mobility::Backends::ActiveRecord::KeyValue.const_get("#{type.capitalize}Translation").
209
207
  where(translatable: self).destroy_all
210
208
  end
211
209
  end
212
210
  end
213
211
  end
212
+
213
+ class Translation < ::ActiveRecord::Base
214
+ self.abstract_class = true
215
+
216
+ belongs_to :translatable, polymorphic: true, touch: true
217
+
218
+ validates :key, presence: true, uniqueness: { scope: [:translatable_id, :translatable_type, :locale], case_sensitive: true }
219
+ validates :translatable, presence: true
220
+ validates :locale, presence: true
221
+ end
222
+
223
+ class TextTranslation < Translation
224
+ self.table_name = "mobility_text_translations"
225
+ end
226
+
227
+ class StringTranslation < Translation
228
+ self.table_name = "mobility_string_translations"
229
+ end
214
230
  end
215
231
 
216
232
  register_backend(:active_record_key_value, ActiveRecord::KeyValue)
@@ -1,7 +1,6 @@
1
1
  # frozen-string-literal: true
2
2
  require "mobility/backends/active_record"
3
3
  require "mobility/backends/table"
4
- require "mobility/active_record/model_translation"
5
4
 
6
5
  module Mobility
7
6
  module Backends
@@ -116,10 +115,10 @@ columns to that table.
116
115
 
117
116
  # @param [String] attr Attribute name
118
117
  # @param [Symbol] _locale Locale
119
- # @return [Mobility::Arel::Attribute] Arel node for column on translation table
118
+ # @return [Mobility::Plugins::Arel::Attribute] Arel node for column on translation table
120
119
  def build_node(attr, locale)
121
120
  aliased_table = model_class.const_get(subclass_name).arel_table.alias(table_alias(locale))
122
- Arel::Attribute.new(aliased_table, attr, locale, self)
121
+ Plugins::Arel::Attribute.new(aliased_table, attr, locale, self)
123
122
  end
124
123
 
125
124
  # Joins translations using either INNER/OUTER join appropriate to the
@@ -190,7 +189,7 @@ columns to that table.
190
189
  # we need an OUTER JOIN. In the second case, one attribute is matched
191
190
  # against a non-nil value, so we can use an INNER JOIN.
192
191
  #
193
- class Visitor < Arel::Visitor
192
+ class Visitor < Plugins::Arel::Visitor
194
193
  private
195
194
 
196
195
  def visit_Arel_Nodes_Equality(object)
@@ -227,7 +226,7 @@ columns to that table.
227
226
  end
228
227
  end
229
228
 
230
- def visit_Mobility_Arel_Attribute(object)
229
+ def visit_Mobility_Plugins_Arel_Attribute(object)
231
230
  # We compare table names here to ensure that attributes defined on
232
231
  # different backends but the same table will correctly get an OUTER
233
232
  # join when required. Use options[:table_name] here since we don't
@@ -245,7 +244,7 @@ columns to that table.
245
244
  if self.const_defined?(subclass_name, false)
246
245
  const_get(subclass_name, false)
247
246
  else
248
- const_set(subclass_name, Class.new(Mobility::ActiveRecord::ModelTranslation))
247
+ const_set(subclass_name, Class.new(Translation))
249
248
  end
250
249
 
251
250
  translation_class.table_name = options[:table_name]
@@ -303,6 +302,12 @@ columns to that table.
303
302
  destroy(empty_translations) if empty_translations.any?
304
303
  end
305
304
  end
305
+
306
+ # Subclassed dynamically to generate translation class.
307
+ class Translation < ::ActiveRecord::Base
308
+ self.abstract_class = true
309
+ validates :locale, presence: true
310
+ end
306
311
  end
307
312
 
308
313
  register_backend(:active_record_table, ActiveRecord::Table)