mobility 1.0.0.beta2 → 1.0.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
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)