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.
- 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)
|