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.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +3 -2
- data.tar.gz.sig +0 -0
- data/CHANGELOG.md +5 -0
- data/Gemfile.lock +19 -0
- data/README.md +4 -4
- data/lib/mobility.rb +60 -6
- data/lib/mobility/backends/active_record.rb +1 -1
- data/lib/mobility/backends/active_record/column.rb +1 -1
- data/lib/mobility/backends/active_record/container.rb +4 -4
- data/lib/mobility/backends/active_record/hstore.rb +3 -3
- data/lib/mobility/backends/active_record/json.rb +3 -3
- data/lib/mobility/backends/active_record/jsonb.rb +3 -3
- data/lib/mobility/backends/active_record/key_value.rb +27 -11
- data/lib/mobility/backends/active_record/table.rb +11 -6
- data/lib/mobility/backends/sequel.rb +32 -0
- data/lib/mobility/backends/sequel/container.rb +5 -3
- data/lib/mobility/backends/sequel/key_value.rb +79 -12
- data/lib/mobility/backends/sequel/pg_hash.rb +6 -6
- data/lib/mobility/backends/sequel/table.rb +18 -8
- data/lib/mobility/backends/table.rb +11 -6
- data/lib/mobility/plugins/active_record.rb +3 -0
- data/lib/mobility/plugins/active_record/backend.rb +2 -0
- data/lib/mobility/plugins/active_record/query.rb +2 -2
- data/lib/mobility/plugins/arel.rb +125 -0
- data/lib/mobility/plugins/arel/nodes.rb +15 -0
- data/lib/mobility/plugins/arel/nodes/pg_ops.rb +134 -0
- data/lib/mobility/plugins/sequel/dirty.rb +1 -1
- data/lib/mobility/version.rb +1 -1
- metadata +5 -17
- metadata.gz.sig +0 -0
- data/lib/mobility/active_record/model_translation.rb +0 -14
- data/lib/mobility/active_record/string_translation.rb +0 -10
- data/lib/mobility/active_record/text_translation.rb +0 -10
- data/lib/mobility/active_record/translation.rb +0 -14
- data/lib/mobility/arel.rb +0 -49
- data/lib/mobility/arel/nodes.rb +0 -13
- data/lib/mobility/arel/nodes/pg_ops.rb +0 -132
- data/lib/mobility/arel/visitor.rb +0 -61
- data/lib/mobility/sequel/column_changes.rb +0 -28
- data/lib/mobility/sequel/hash_initializer.rb +0 -21
- data/lib/mobility/sequel/model_translation.rb +0 -20
- data/lib/mobility/sequel/sql.rb +0 -16
- data/lib/mobility/sequel/string_translation.rb +0 -10
- data/lib/mobility/sequel/text_translation.rb +0 -10
- data/lib/mobility/sequel/translation.rb +0 -53
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8658079d8c9fad02763385921421140d2410cde1d505c286627de5a8c1819612
|
4
|
+
data.tar.gz: 9bb012a9f564971e0c24fd3015e20e17384d7cbd77f2f0a5f1f1505e5262277a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0a4a8a38a27d6f727091062010087466c85bfe48ce369395adb5501bd9875cfba21a56bce6a13b92b5cf83746883934f4161835f1336adedd9539bbf1138c51b
|
7
|
+
data.tar.gz: ca65fdaf7af558d235fdb5ba45347b9ca2319d9e6d69ddf7611afa2a50a477a30998316ce8661ca640ced1d09cd05f6ff282b1edfebd79abf4830c142bdf95df
|
checksums.yaml.gz.sig
CHANGED
@@ -1,2 +1,3 @@
|
|
1
|
-
|
2
|
-
i
|
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
|
data/CHANGELOG.md
CHANGED
@@ -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
|
data/Gemfile.lock
CHANGED
@@ -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.
|
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.
|
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
|
94
|
+
Mobility.configure do
|
95
95
|
# PLUGINS
|
96
96
|
|
97
|
-
|
97
|
+
plugins do
|
98
98
|
backend :key_value
|
99
99
|
|
100
100
|
active_record
|
data/lib/mobility.rb
CHANGED
@@ -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.
|
10
|
-
support defining backend accessors on a class.
|
9
|
+
on a class.
|
11
10
|
|
12
|
-
|
13
|
-
and
|
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
|
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
|
@@ -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(::
|
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] ||=
|
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 < ::
|
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
|
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,
|
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
|
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(
|
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)
|