mobility 1.0.0.alpha → 1.0.0.beta1
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 +0 -0
- data.tar.gz.sig +0 -0
- data/CHANGELOG.md +17 -1
- data/Gemfile.lock +15 -84
- data/README.md +3 -3
- data/lib/mobility.rb +6 -2
- data/lib/mobility/arel.rb +1 -1
- data/lib/mobility/backend.rb +8 -10
- data/lib/mobility/backends.rb +1 -1
- data/lib/mobility/backends/active_record/container.rb +2 -5
- data/lib/mobility/backends/active_record/hstore.rb +1 -1
- data/lib/mobility/backends/active_record/key_value.rb +1 -1
- data/lib/mobility/backends/active_record/serialized.rb +4 -0
- data/lib/mobility/backends/active_record/table.rb +1 -1
- data/lib/mobility/backends/container.rb +10 -2
- data/lib/mobility/backends/hash_valued.rb +4 -0
- data/lib/mobility/backends/jsonb.rb +1 -1
- data/lib/mobility/backends/key_value.rb +12 -15
- data/lib/mobility/backends/sequel.rb +2 -2
- data/lib/mobility/backends/sequel/container.rb +3 -5
- data/lib/mobility/backends/sequel/hstore.rb +1 -1
- data/lib/mobility/backends/sequel/json.rb +1 -0
- data/lib/mobility/backends/sequel/serialized.rb +4 -0
- data/lib/mobility/backends/table.rb +18 -23
- data/lib/mobility/pluggable.rb +21 -1
- data/lib/mobility/plugins.rb +2 -0
- data/lib/mobility/plugins/active_model/dirty.rb +11 -5
- data/lib/mobility/plugins/active_record/uniqueness_validation.rb +1 -1
- data/lib/mobility/plugins/backend.rb +38 -15
- data/lib/mobility/plugins/cache.rb +12 -5
- data/lib/mobility/plugins/default.rb +1 -1
- data/lib/mobility/plugins/fallbacks.rb +4 -4
- data/lib/mobility/plugins/fallthrough_accessors.rb +5 -6
- data/lib/mobility/plugins/locale_accessors.rb +2 -5
- data/lib/mobility/plugins/presence.rb +1 -1
- data/lib/mobility/plugins/reader.rb +2 -2
- data/lib/mobility/plugins/sequel/dirty.rb +1 -1
- data/lib/mobility/plugins/writer.rb +1 -1
- data/lib/mobility/version.rb +1 -1
- data/lib/rails/generators/mobility/templates/initializer.rb +2 -2
- metadata +2 -2
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a27c475aac12e8c93750cd6b11b7b339912c95bb24ada1e579c8f87598359388
|
4
|
+
data.tar.gz: faf2187673842e059b204715e774b2ef22d0a98e6162d7014ef875236a0db192
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 51dfb02fb8624897834dbc9260eb7edc67f6120f2971de120f7084e59df0865a027eca3ccae435ba77604fa8086760a1c682b9879a4c625be71368fa21d3b2c7
|
7
|
+
data.tar.gz: 5133980f0433ba31d157ebda7e1a8028dc84aa8d8dc7ab6b0df94861c347e60f34b09665eb890341998080be5256bea566f7e0dea62f96f6c85fcfd931319969
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data.tar.gz.sig
CHANGED
Binary file
|
data/CHANGELOG.md
CHANGED
@@ -1,6 +1,22 @@
|
|
1
1
|
# Mobility Changelog
|
2
2
|
|
3
|
-
## 1.0
|
3
|
+
## 1.0
|
4
|
+
|
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
|
+
|
7
|
+
## 1.0.0.beta1 (pre-release)
|
8
|
+
|
9
|
+
- Remove `Mobility::Backend#apply_plugin`
|
10
|
+
([#454](https://github.com/shioyama/mobility/pull/454))
|
11
|
+
- Instance exec configure block if it takes no arguments
|
12
|
+
([#456](https://github.com/shioyama/mobility/pull/456))
|
13
|
+
- Raise an exception if invalid options are passed to Translations initializer
|
14
|
+
([#457](https://github.com/shioyama/mobility/pull/457/files))
|
15
|
+
- Fix Ruby 2.7 deprecation warnings
|
16
|
+
([#460](https://github.com/shioyama/mobility/pull/460))
|
17
|
+
|
18
|
+
## 1.0.0.alpha (pre-release)
|
19
|
+
|
4
20
|
- Default fallbacks plugin to `true` when enabled
|
5
21
|
([#447](https://github.com/shioyama/mobility/pull/447))
|
6
22
|
- Remove `Mobility::Backend.method_name`
|
data/Gemfile.lock
CHANGED
@@ -1,38 +1,3 @@
|
|
1
|
-
GIT
|
2
|
-
remote: https://github.com/rails/rails.git
|
3
|
-
revision: 0a608bd987fde4f9bc5bcf4bcebdb181d199cf4f
|
4
|
-
specs:
|
5
|
-
actionpack (6.1.0.alpha)
|
6
|
-
actionview (= 6.1.0.alpha)
|
7
|
-
activesupport (= 6.1.0.alpha)
|
8
|
-
rack (~> 2.0, >= 2.0.9)
|
9
|
-
rack-test (>= 0.6.3)
|
10
|
-
rails-dom-testing (~> 2.0)
|
11
|
-
rails-html-sanitizer (~> 1.0, >= 1.2.0)
|
12
|
-
actionview (6.1.0.alpha)
|
13
|
-
activesupport (= 6.1.0.alpha)
|
14
|
-
builder (~> 3.1)
|
15
|
-
erubi (~> 1.4)
|
16
|
-
rails-dom-testing (~> 2.0)
|
17
|
-
rails-html-sanitizer (~> 1.1, >= 1.2.0)
|
18
|
-
activemodel (6.1.0.alpha)
|
19
|
-
activesupport (= 6.1.0.alpha)
|
20
|
-
activerecord (6.1.0.alpha)
|
21
|
-
activemodel (= 6.1.0.alpha)
|
22
|
-
activesupport (= 6.1.0.alpha)
|
23
|
-
activesupport (6.1.0.alpha)
|
24
|
-
concurrent-ruby (~> 1.0, >= 1.0.2)
|
25
|
-
i18n (>= 1.6, < 2)
|
26
|
-
minitest (>= 5.1)
|
27
|
-
tzinfo (~> 2.0)
|
28
|
-
zeitwerk (~> 2.3)
|
29
|
-
railties (6.1.0.alpha)
|
30
|
-
actionpack (= 6.1.0.alpha)
|
31
|
-
activesupport (= 6.1.0.alpha)
|
32
|
-
method_source
|
33
|
-
rake (>= 0.8.7)
|
34
|
-
thor (~> 1.0)
|
35
|
-
|
36
1
|
PATH
|
37
2
|
remote: .
|
38
3
|
specs:
|
@@ -43,22 +8,15 @@ PATH
|
|
43
8
|
GEM
|
44
9
|
remote: https://rubygems.org/
|
45
10
|
specs:
|
46
|
-
|
47
|
-
|
48
|
-
benchmark-ips (2.8.2)
|
49
|
-
builder (3.2.4)
|
11
|
+
allocation_stats (0.1.5)
|
12
|
+
benchmark-ips (2.8.3)
|
50
13
|
byebug (11.1.3)
|
51
14
|
coderay (1.1.3)
|
52
15
|
concurrent-ruby (1.1.7)
|
53
|
-
crass (1.0.6)
|
54
16
|
database_cleaner (1.8.5)
|
55
17
|
diff-lcs (1.4.4)
|
56
|
-
erubi (1.9.0)
|
57
18
|
ffi (1.13.1)
|
58
19
|
formatador (0.2.5)
|
59
|
-
generator_spec (0.9.4)
|
60
|
-
activesupport (>= 3.0.0)
|
61
|
-
railties (>= 3.0.0)
|
62
20
|
guard (2.16.2)
|
63
21
|
formatador (>= 0.2.4)
|
64
22
|
listen (>= 2.7, < 4.0)
|
@@ -78,20 +36,12 @@ GEM
|
|
78
36
|
listen (3.2.1)
|
79
37
|
rb-fsevent (~> 0.10, >= 0.10.3)
|
80
38
|
rb-inotify (~> 0.9, >= 0.9.10)
|
81
|
-
|
82
|
-
crass (~> 1.0.2)
|
83
|
-
nokogiri (>= 1.5.9)
|
84
|
-
lumberjack (1.2.7)
|
39
|
+
lumberjack (1.2.8)
|
85
40
|
method_source (1.0.0)
|
86
|
-
mini_portile2 (2.4.0)
|
87
|
-
minitest (5.14.2)
|
88
41
|
nenv (0.3.0)
|
89
|
-
nokogiri (1.10.10)
|
90
|
-
mini_portile2 (~> 2.4.0)
|
91
42
|
notiffany (0.1.3)
|
92
43
|
nenv (~> 0.1)
|
93
44
|
shellany (~> 0.0)
|
94
|
-
pg (1.2.3)
|
95
45
|
pry (0.13.1)
|
96
46
|
coderay (~> 1.1)
|
97
47
|
method_source (~> 1.0)
|
@@ -99,58 +49,39 @@ GEM
|
|
99
49
|
byebug (~> 11.0)
|
100
50
|
pry (~> 0.13.0)
|
101
51
|
rack (2.2.3)
|
102
|
-
rack-test (1.1.0)
|
103
|
-
rack (>= 1.0, < 3)
|
104
|
-
rails (0.9.5)
|
105
|
-
actionmailer (>= 0.6.1)
|
106
|
-
actionpack (>= 1.4.0)
|
107
|
-
activerecord (>= 1.6.0)
|
108
|
-
rake (>= 0.4.15)
|
109
|
-
rails-dom-testing (2.0.3)
|
110
|
-
activesupport (>= 4.2.0)
|
111
|
-
nokogiri (>= 1.6)
|
112
|
-
rails-html-sanitizer (1.3.0)
|
113
|
-
loofah (~> 2.3)
|
114
52
|
rake (12.3.3)
|
115
53
|
rb-fsevent (0.10.4)
|
116
54
|
rb-inotify (0.10.1)
|
117
55
|
ffi (~> 1.0)
|
118
56
|
request_store (1.5.0)
|
119
57
|
rack (>= 1.4)
|
120
|
-
rspec (3.
|
121
|
-
rspec-core (~> 3.
|
122
|
-
rspec-expectations (~> 3.
|
123
|
-
rspec-mocks (~> 3.
|
124
|
-
rspec-core (3.
|
125
|
-
rspec-support (~> 3.
|
126
|
-
rspec-expectations (3.
|
58
|
+
rspec (3.10.0)
|
59
|
+
rspec-core (~> 3.10.0)
|
60
|
+
rspec-expectations (~> 3.10.0)
|
61
|
+
rspec-mocks (~> 3.10.0)
|
62
|
+
rspec-core (3.10.0)
|
63
|
+
rspec-support (~> 3.10.0)
|
64
|
+
rspec-expectations (3.10.0)
|
127
65
|
diff-lcs (>= 1.2.0, < 2.0)
|
128
|
-
rspec-support (~> 3.
|
129
|
-
rspec-mocks (3.
|
66
|
+
rspec-support (~> 3.10.0)
|
67
|
+
rspec-mocks (3.10.0)
|
130
68
|
diff-lcs (>= 1.2.0, < 2.0)
|
131
|
-
rspec-support (~> 3.
|
132
|
-
rspec-support (3.
|
69
|
+
rspec-support (~> 3.10.0)
|
70
|
+
rspec-support (3.10.0)
|
133
71
|
shellany (0.0.1)
|
134
72
|
thor (1.0.1)
|
135
|
-
tzinfo (2.0.2)
|
136
|
-
concurrent-ruby (~> 1.0)
|
137
73
|
yard (0.9.25)
|
138
|
-
zeitwerk (2.4.0)
|
139
74
|
|
140
75
|
PLATFORMS
|
141
76
|
ruby
|
142
77
|
|
143
78
|
DEPENDENCIES
|
144
|
-
|
145
|
-
activesupport!
|
79
|
+
allocation_stats
|
146
80
|
benchmark-ips
|
147
81
|
database_cleaner (~> 1.5, >= 1.5.3)
|
148
|
-
generator_spec (~> 0.9.4)
|
149
82
|
guard-rspec
|
150
83
|
mobility!
|
151
|
-
pg
|
152
84
|
pry-byebug
|
153
|
-
rails
|
154
85
|
rake (~> 12, >= 12.2.1)
|
155
86
|
rspec (~> 3.0)
|
156
87
|
yard (~> 0.9.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.beta, 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).**
|
@@ -54,11 +54,11 @@ section of the wiki.
|
|
54
54
|
Installation
|
55
55
|
------------
|
56
56
|
|
57
|
-
To use the latest
|
57
|
+
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',
|
61
|
+
gem 'mobility', '~> 1.0.0.beta1'
|
62
62
|
```
|
63
63
|
|
64
64
|
For the latest stable version of Mobility, see the readme on the
|
data/lib/mobility.rb
CHANGED
@@ -57,9 +57,13 @@ module Mobility
|
|
57
57
|
|
58
58
|
# Configure Mobility
|
59
59
|
# @yield [Mobility::Translations]
|
60
|
-
def configure
|
60
|
+
def configure(&block)
|
61
61
|
translates_with(Class.new(Translations)) unless @translations_class
|
62
|
-
|
62
|
+
if block.arity == 0
|
63
|
+
translations_class.instance_exec(&block)
|
64
|
+
else
|
65
|
+
yield translations_class
|
66
|
+
end
|
63
67
|
end
|
64
68
|
# @!endgroup
|
65
69
|
|
data/lib/mobility/arel.rb
CHANGED
@@ -38,7 +38,7 @@ module Mobility
|
|
38
38
|
attr_reader :locale
|
39
39
|
attr_reader :attribute_name
|
40
40
|
|
41
|
-
def initialize(relation, column_name, locale, backend_class, attribute_name
|
41
|
+
def initialize(relation, column_name, locale, backend_class, attribute_name = nil)
|
42
42
|
@backend_class = backend_class
|
43
43
|
@locale = locale
|
44
44
|
@attribute_name = attribute_name || column_name
|
data/lib/mobility/backend.rb
CHANGED
@@ -100,7 +100,7 @@ On top of this, a backend will normally:
|
|
100
100
|
# @param [Symbol] locale Locale to read
|
101
101
|
# @return [TrueClass,FalseClass] Whether translation is present for locale
|
102
102
|
def present?(locale, options = {})
|
103
|
-
Util.present?(read(locale, options))
|
103
|
+
Util.present?(read(locale, **options))
|
104
104
|
end
|
105
105
|
|
106
106
|
# @!method model_class
|
@@ -120,6 +120,13 @@ On top of this, a backend will normally:
|
|
120
120
|
|
121
121
|
# Defines setup hooks for backend to customize model class.
|
122
122
|
module ClassMethods
|
123
|
+
# Returns valid option keys for this backend. This is overriden in
|
124
|
+
# backends to define which keys are valid for each backend class.
|
125
|
+
# @return [Array]
|
126
|
+
def valid_keys
|
127
|
+
[]
|
128
|
+
end
|
129
|
+
|
123
130
|
# Assign block to be called on model class.
|
124
131
|
# @yield [attribute_names, options]
|
125
132
|
# @note When called multiple times, setup blocks will be appended
|
@@ -179,15 +186,6 @@ On top of this, a backend will normally:
|
|
179
186
|
EOM
|
180
187
|
end
|
181
188
|
|
182
|
-
# Called from plugins to apply custom processing for this backend.
|
183
|
-
# Name is the name of the plugin.
|
184
|
-
# @param [Symbol] name Name of plugin
|
185
|
-
# @return [Boolean] Whether the plugin was applied
|
186
|
-
# @note This is currently only called by Plugins::Cache.
|
187
|
-
def apply_plugin(_)
|
188
|
-
false
|
189
|
-
end
|
190
|
-
|
191
189
|
# Show useful information about this backend class, if it has no name.
|
192
190
|
# @return [String]
|
193
191
|
def inspect
|
data/lib/mobility/backends.rb
CHANGED
@@ -5,7 +5,7 @@ module Mobility
|
|
5
5
|
class << self
|
6
6
|
# @param [Symbol, Object] backend Name of backend to load.
|
7
7
|
def load_backend(name)
|
8
|
-
return name if Module === name
|
8
|
+
return name if Module === name || name.nil?
|
9
9
|
|
10
10
|
unless (backend = @backends[name])
|
11
11
|
require "mobility/backends/#{name}"
|
@@ -1,5 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
require "mobility/backends/active_record"
|
3
|
+
require "mobility/backends/container"
|
3
4
|
require "mobility/arel/nodes/pg_ops"
|
4
5
|
|
5
6
|
module Mobility
|
@@ -11,11 +12,7 @@ Implements the {Mobility::Backends::Container} backend for ActiveRecord models.
|
|
11
12
|
=end
|
12
13
|
class ActiveRecord::Container
|
13
14
|
include ActiveRecord
|
14
|
-
|
15
|
-
# @!method column_name
|
16
|
-
# Returns name of json or jsonb column used to store translations
|
17
|
-
# @return [Symbol] (:translations) Name of translations column
|
18
|
-
option_reader :column_name
|
15
|
+
include Container
|
19
16
|
|
20
17
|
# @!group Backend Accessors
|
21
18
|
#
|
@@ -18,7 +18,7 @@ Implements the {Mobility::Backends::Hstore} backend for ActiveRecord models.
|
|
18
18
|
|
19
19
|
# @!macro backend_writer
|
20
20
|
def write(locale, value, options = {})
|
21
|
-
super(locale, value && value.to_s, options)
|
21
|
+
super(locale, value && value.to_s, **options)
|
22
22
|
end
|
23
23
|
# @!endgroup
|
24
24
|
|
@@ -51,7 +51,7 @@ Implements the {Mobility::Backends::KeyValue} backend for ActiveRecord models.
|
|
51
51
|
# translation table value column
|
52
52
|
def build_node(attr, locale)
|
53
53
|
aliased_table = class_name.arel_table.alias(table_alias(attr, locale))
|
54
|
-
Arel::Attribute.new(aliased_table, :value, locale, self,
|
54
|
+
Arel::Attribute.new(aliased_table, :value, locale, self, attr.to_sym)
|
55
55
|
end
|
56
56
|
|
57
57
|
# Joins translations using either INNER/OUTER join appropriate to the query.
|
@@ -30,6 +30,10 @@ Implements {Mobility::Backends::Serialized} backend for ActiveRecord models.
|
|
30
30
|
include ActiveRecord
|
31
31
|
include HashValued
|
32
32
|
|
33
|
+
def self.valid_keys
|
34
|
+
super + [:format]
|
35
|
+
end
|
36
|
+
|
33
37
|
# @!group Backend Configuration
|
34
38
|
# @param (see Backends::Serialized.configure)
|
35
39
|
# @option (see Backends::Serialized.configure)
|
@@ -283,7 +283,7 @@ columns to that table.
|
|
283
283
|
|
284
284
|
# Returns translation for a given locale, or builds one if none is present.
|
285
285
|
# @param [Symbol] locale
|
286
|
-
def translation_for(locale,
|
286
|
+
def translation_for(locale, **)
|
287
287
|
translation = translations.in_locale(locale)
|
288
288
|
translation ||= translations.build(locale: locale)
|
289
289
|
translation
|
@@ -19,8 +19,16 @@ stored).
|
|
19
19
|
|
20
20
|
=end
|
21
21
|
module Container
|
22
|
+
def self.included(backend_class)
|
23
|
+
backend_class.extend ClassMethods
|
24
|
+
backend_class.option_reader :column_name
|
25
|
+
end
|
26
|
+
|
27
|
+
module ClassMethods
|
28
|
+
def valid_keys
|
29
|
+
[:column_name]
|
30
|
+
end
|
31
|
+
end
|
22
32
|
end
|
23
|
-
|
24
|
-
register_backend(:container, Container)
|
25
33
|
end
|
26
34
|
end
|
@@ -36,6 +36,10 @@ Defines read and write methods that access the value at a key with value
|
|
36
36
|
end
|
37
37
|
|
38
38
|
module ClassMethods
|
39
|
+
def valid_keys
|
40
|
+
[:column_prefix, :column_suffix]
|
41
|
+
end
|
42
|
+
|
39
43
|
def configure(options)
|
40
44
|
options[:column_affix] = "#{options[:column_prefix]}%s#{options[:column_suffix]}"
|
41
45
|
end
|
@@ -54,13 +54,13 @@ other backends on model (otherwise one will overwrite the other).
|
|
54
54
|
|
55
55
|
# @!group Backend Accessors
|
56
56
|
# @!macro backend_reader
|
57
|
-
def read(locale, options
|
58
|
-
translation_for(locale, options).value
|
57
|
+
def read(locale, **options)
|
58
|
+
translation_for(locale, **options).value
|
59
59
|
end
|
60
60
|
|
61
61
|
# @!macro backend_writer
|
62
|
-
def write(locale, value, options
|
63
|
-
translation_for(locale, options).value = value
|
62
|
+
def write(locale, value, **options)
|
63
|
+
translation_for(locale, **options).value = value
|
64
64
|
end
|
65
65
|
# @!endgroup
|
66
66
|
|
@@ -83,6 +83,10 @@ other backends on model (otherwise one will overwrite the other).
|
|
83
83
|
end
|
84
84
|
|
85
85
|
module ClassMethods
|
86
|
+
def valid_keys
|
87
|
+
[:type, :association_name, :class_name]
|
88
|
+
end
|
89
|
+
|
86
90
|
# @!group Backend Configuration
|
87
91
|
# @option options [Symbol,String] type Column type to use
|
88
92
|
# @option options [Symbol] association_name (:<type>_translations) Name
|
@@ -100,16 +104,9 @@ other backends on model (otherwise one will overwrite the other).
|
|
100
104
|
end
|
101
105
|
end
|
102
106
|
|
103
|
-
# Apply custom processing for plugin
|
104
|
-
|
105
|
-
|
106
|
-
def apply_plugin(name)
|
107
|
-
if name == :cache
|
108
|
-
include self::Cache
|
109
|
-
true
|
110
|
-
else
|
111
|
-
super
|
112
|
-
end
|
107
|
+
# Apply custom processing for cache plugin
|
108
|
+
def include_cache
|
109
|
+
include self::Cache
|
113
110
|
end
|
114
111
|
|
115
112
|
def table_alias(attr, locale)
|
@@ -123,7 +120,7 @@ other backends on model (otherwise one will overwrite the other).
|
|
123
120
|
if cache.has_key?(locale)
|
124
121
|
cache[locale]
|
125
122
|
else
|
126
|
-
cache[locale] = super(locale, options)
|
123
|
+
cache[locale] = super(locale, **options)
|
127
124
|
end
|
128
125
|
end
|
129
126
|
|
@@ -1,6 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
require "mobility/backends/sequel
|
2
|
+
require "mobility/backends/sequel"
|
3
3
|
require "mobility/backends/sequel/jsonb"
|
4
|
+
require "mobility/backends/container"
|
4
5
|
|
5
6
|
module Mobility
|
6
7
|
module Backends
|
@@ -11,10 +12,7 @@ Implements the {Mobility::Backends::Container} backend for Sequel models.
|
|
11
12
|
=end
|
12
13
|
class Sequel::Container
|
13
14
|
include Sequel
|
14
|
-
|
15
|
-
# @!method column_name
|
16
|
-
# @return [Symbol] (:translations) Name of translations column
|
17
|
-
option_reader :column_name
|
15
|
+
include Container
|
18
16
|
|
19
17
|
# @!group Backend Accessors
|
20
18
|
#
|
@@ -20,7 +20,7 @@ Implements the {Mobility::Backends::Hstore} backend for Sequel models.
|
|
20
20
|
# @!group Backend Accessors
|
21
21
|
# @!macro backend_writer
|
22
22
|
def write(locale, value, options = {})
|
23
|
-
super(locale, value && value.to_s, options)
|
23
|
+
super(locale, value && value.to_s, **options)
|
24
24
|
end
|
25
25
|
# @!endgroup
|
26
26
|
|
@@ -36,6 +36,10 @@ Sequel serialization plugin.
|
|
36
36
|
include Sequel
|
37
37
|
include HashValued
|
38
38
|
|
39
|
+
def self.valid_keys
|
40
|
+
super + [:format]
|
41
|
+
end
|
42
|
+
|
39
43
|
# @!group Backend Configuration
|
40
44
|
# @param (see Backends::Serialized.configure)
|
41
45
|
# @option (see Backends::Serialized.configure)
|
@@ -83,13 +83,13 @@ set.
|
|
83
83
|
|
84
84
|
# @!group Backend Accessors
|
85
85
|
# @!macro backend_reader
|
86
|
-
def read(locale, options
|
87
|
-
translation_for(locale, options).send(attribute)
|
86
|
+
def read(locale, **options)
|
87
|
+
translation_for(locale, **options).send(attribute)
|
88
88
|
end
|
89
89
|
|
90
90
|
# @!macro backend_writer
|
91
|
-
def write(locale, value, options
|
92
|
-
translation_for(locale, options).send("#{attribute}=", value)
|
91
|
+
def write(locale, value, **options)
|
92
|
+
translation_for(locale, **options).send("#{attribute}=", value)
|
93
93
|
end
|
94
94
|
# @!endgroup
|
95
95
|
|
@@ -104,25 +104,22 @@ set.
|
|
104
104
|
model.send(association_name)
|
105
105
|
end
|
106
106
|
|
107
|
-
def self.included(
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
107
|
+
def self.included(backend_class)
|
108
|
+
backend_class.extend ClassMethods
|
109
|
+
backend_class.option_reader :association_name
|
110
|
+
backend_class.option_reader :subclass_name
|
111
|
+
backend_class.option_reader :foreign_key
|
112
|
+
backend_class.option_reader :table_name
|
113
113
|
end
|
114
114
|
|
115
115
|
module ClassMethods
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
else
|
124
|
-
super
|
125
|
-
end
|
116
|
+
def valid_keys
|
117
|
+
[:association_name, :subclass_name, :foreign_key, :table_name]
|
118
|
+
end
|
119
|
+
|
120
|
+
# Apply custom processing for cache plugin
|
121
|
+
def include_cache
|
122
|
+
include self::Cache
|
126
123
|
end
|
127
124
|
|
128
125
|
def table_alias(locale)
|
@@ -138,7 +135,7 @@ set.
|
|
138
135
|
if cache.has_key?(locale)
|
139
136
|
cache[locale]
|
140
137
|
else
|
141
|
-
cache[locale] = super(locale, options)
|
138
|
+
cache[locale] = super(locale, **options)
|
142
139
|
end
|
143
140
|
end
|
144
141
|
|
@@ -157,7 +154,5 @@ set.
|
|
157
154
|
end
|
158
155
|
end
|
159
156
|
end
|
160
|
-
|
161
|
-
register_backend(:table, Table)
|
162
157
|
end
|
163
158
|
end
|
data/lib/mobility/pluggable.rb
CHANGED
@@ -17,6 +17,10 @@ Works with {Mobility::Plugin}. (Subclassed by {Mobility::Translations}.)
|
|
17
17
|
Plugin.configure(self, defaults, &block)
|
18
18
|
end
|
19
19
|
|
20
|
+
def included_plugins
|
21
|
+
included_modules.grep(Plugin)
|
22
|
+
end
|
23
|
+
|
20
24
|
def defaults
|
21
25
|
@defaults ||= {}
|
22
26
|
end
|
@@ -28,9 +32,25 @@ Works with {Mobility::Plugin}. (Subclassed by {Mobility::Translations}.)
|
|
28
32
|
end
|
29
33
|
|
30
34
|
def initialize(*, **options)
|
31
|
-
|
35
|
+
initialize_options(options)
|
36
|
+
validate_options(@options)
|
32
37
|
end
|
33
38
|
|
34
39
|
attr_reader :options
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def initialize_options(options)
|
44
|
+
@options = self.class.defaults.merge(options)
|
45
|
+
end
|
46
|
+
|
47
|
+
# This is overridden by backend plugin to exclude mixed-in backend options.
|
48
|
+
def validate_options(options)
|
49
|
+
plugin_keys = self.class.included_plugins.map { |p| Plugins.lookup_name(p) }
|
50
|
+
extra_keys = options.keys - plugin_keys
|
51
|
+
raise InvalidOptionKey, "No plugin configured for these keys: #{extra_keys.join(', ')}." unless extra_keys.empty?
|
52
|
+
end
|
53
|
+
|
54
|
+
class InvalidOptionKey < Error; end
|
35
55
|
end
|
36
56
|
end
|
data/lib/mobility/plugins.rb
CHANGED
@@ -14,6 +14,8 @@ declared in any order (dependencies will be resolved).
|
|
14
14
|
class << self
|
15
15
|
# @param [Symbol] name Name of plugin to load.
|
16
16
|
def load_plugin(name)
|
17
|
+
return name if Module === name || name.nil?
|
18
|
+
|
17
19
|
unless (plugin = @plugins[name])
|
18
20
|
require "mobility/plugins/#{name}"
|
19
21
|
raise LoadError, "plugin #{name} did not register itself correctly in Mobility::Plugins" unless (plugin = @plugins[name])
|
@@ -80,7 +80,12 @@ the ActiveRecord dirty plugin for more information.
|
|
80
80
|
attribute_names.each do |name|
|
81
81
|
dirty_handler_methods.each_pattern(name) do |method_name, attribute_method|
|
82
82
|
define_method(method_name) do |*args|
|
83
|
-
|
83
|
+
# for %s_changed?(from:, to:) pattern
|
84
|
+
if (kwargs = args.last).is_a?(Hash)
|
85
|
+
mutations_from_mobility.send(attribute_method, Dirty.append_locale(name), *args[0,-1], **kwargs)
|
86
|
+
else
|
87
|
+
mutations_from_mobility.send(attribute_method, Dirty.append_locale(name), *args)
|
88
|
+
end
|
84
89
|
end
|
85
90
|
end
|
86
91
|
|
@@ -130,11 +135,12 @@ the ActiveRecord dirty plugin for more information.
|
|
130
135
|
public_patterns.each do |pattern|
|
131
136
|
method_name = pattern % 'attribute'
|
132
137
|
|
138
|
+
kwargs = pattern == '%s_changed?' ? ', **kwargs' : ''
|
133
139
|
module_eval <<-EOM, __FILE__, __LINE__ + 1
|
134
|
-
def #{method_name}(attr_name, *rest)
|
140
|
+
def #{method_name}(attr_name, *rest#{kwargs})
|
135
141
|
if (mutations_from_mobility.attribute_changed?(attr_name) ||
|
136
142
|
mutations_from_mobility.attribute_previously_changed?(attr_name))
|
137
|
-
mutations_from_mobility.send(#{method_name.inspect}, attr_name, *rest)
|
143
|
+
mutations_from_mobility.send(#{method_name.inspect}, attr_name, *rest#{kwargs})
|
138
144
|
else
|
139
145
|
super
|
140
146
|
end
|
@@ -330,11 +336,11 @@ the ActiveRecord dirty plugin for more information.
|
|
330
336
|
# @!group Backend Accessors
|
331
337
|
# @!macro backend_writer
|
332
338
|
# @param [Hash] options
|
333
|
-
def write(locale, value, options
|
339
|
+
def write(locale, value, **options)
|
334
340
|
locale_accessor = Mobility.normalize_locale_accessor(attribute, locale)
|
335
341
|
if model.changed_attributes.has_key?(locale_accessor) && model.changed_attributes[locale_accessor] == value
|
336
342
|
mutations_from_mobility.restore_attribute!(locale_accessor)
|
337
|
-
elsif read(locale, options.merge(locale: true)) != value
|
343
|
+
elsif read(locale, **options.merge(locale: true)) != value
|
338
344
|
mutations_from_mobility.attribute_will_change!(locale_accessor)
|
339
345
|
end
|
340
346
|
super
|
@@ -32,18 +32,12 @@ Defines:
|
|
32
32
|
|
33
33
|
def initialize(*args, **original_options)
|
34
34
|
super
|
35
|
-
return unless Plugins::Backend.dependencies_satisfied?(self.class)
|
36
35
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
@backend_options = @backend_options.merge(original_options)
|
43
|
-
when NilClass
|
44
|
-
@backend = @backend_options = nil
|
45
|
-
else
|
46
|
-
raise ArgumentError, "backend must be either a backend name, a backend class, or a two-element array"
|
36
|
+
# Validate that the default backend from config has valid keys
|
37
|
+
if (default = self.class.defaults[:backend])
|
38
|
+
name, backend_options = default
|
39
|
+
extra_keys = backend_options.keys - backend.valid_keys
|
40
|
+
raise InvalidOptionKey, "These are not valid #{name} backend keys: #{extra_keys.join(', ')}." unless extra_keys.empty?
|
47
41
|
end
|
48
42
|
|
49
43
|
include InstanceMethods
|
@@ -58,8 +52,7 @@ Defines:
|
|
58
52
|
klass.extend ClassMethods
|
59
53
|
|
60
54
|
if backend
|
61
|
-
@backend_class =
|
62
|
-
build_subclass(klass, backend_options)
|
55
|
+
@backend_class = backend.build_subclass(klass, backend_options)
|
63
56
|
|
64
57
|
backend_class.setup_model(klass, names)
|
65
58
|
|
@@ -83,10 +76,38 @@ Defines:
|
|
83
76
|
raise e, "could not find a #{backend} backend. Did you forget to include an ORM plugin like active_record or sequel?"
|
84
77
|
end
|
85
78
|
|
79
|
+
private
|
80
|
+
|
81
|
+
# Override to extract backend options from options hash.
|
82
|
+
def initialize_options(original_options)
|
83
|
+
super
|
84
|
+
|
85
|
+
case options[:backend]
|
86
|
+
when String, Symbol, Class
|
87
|
+
@backend, @backend_options = options[:backend], options
|
88
|
+
when Array
|
89
|
+
@backend, @backend_options = options[:backend]
|
90
|
+
@backend_options = @backend_options.merge(original_options)
|
91
|
+
when NilClass
|
92
|
+
@backend = @backend_options = nil
|
93
|
+
else
|
94
|
+
raise ArgumentError, "backend must be either a backend name, a backend class, or a two-element array"
|
95
|
+
end
|
96
|
+
|
97
|
+
@backend = load_backend(backend)
|
98
|
+
end
|
99
|
+
|
100
|
+
# Override default validation to exclude backend options, which may be
|
101
|
+
# mixed in with plugin options.
|
102
|
+
def validate_options(options)
|
103
|
+
return super unless backend
|
104
|
+
super(options.slice(*(options.keys - backend.valid_keys)))
|
105
|
+
end
|
106
|
+
|
86
107
|
# Override default argument-handling in DSL to store kwargs passed along
|
87
108
|
# with plugin name.
|
88
|
-
def self.configure_default(defaults, key,
|
89
|
-
defaults[key] = [
|
109
|
+
def self.configure_default(defaults, key, backend = nil, backend_options = {})
|
110
|
+
defaults[key] = [backend, backend_options] if backend
|
90
111
|
end
|
91
112
|
|
92
113
|
module InstanceMethods
|
@@ -131,6 +152,8 @@ Defines:
|
|
131
152
|
@mobility_backend_classes ||= {}
|
132
153
|
end
|
133
154
|
end
|
155
|
+
|
156
|
+
class InvalidOptionKey < Error; end
|
134
157
|
end
|
135
158
|
|
136
159
|
register_plugin(:backend, Backend)
|
@@ -7,8 +7,7 @@ module Mobility
|
|
7
7
|
Caches values fetched from the backend so subsequent fetches can be performed
|
8
8
|
more quickly. The cache stores cached values in a simple hash, which is not
|
9
9
|
optimal for some storage strategies, so some backends (KeyValue, Table) use a
|
10
|
-
custom module
|
11
|
-
details see the documentation for these backends.
|
10
|
+
custom module by defining a method, +include_cache+, on the backend class.
|
12
11
|
|
13
12
|
The cache is reset when one of a set of events happens (saving, reloading,
|
14
13
|
etc.). See {BackendResetter} for details.
|
@@ -28,12 +27,20 @@ Values are added to the cache in two ways:
|
|
28
27
|
# Applies cache plugin to attributes.
|
29
28
|
included_hook do |_, backend_class|
|
30
29
|
if options[:cache]
|
31
|
-
|
30
|
+
if backend_class.respond_to?(:include_cache)
|
31
|
+
backend_class.include_cache
|
32
|
+
else
|
33
|
+
include_cache(backend_class)
|
34
|
+
end
|
32
35
|
end
|
33
36
|
end
|
34
37
|
|
35
38
|
private
|
36
39
|
|
40
|
+
def include_cache(backend_class)
|
41
|
+
backend_class.include BackendMethods
|
42
|
+
end
|
43
|
+
|
37
44
|
# Used in ORM cache plugins
|
38
45
|
def define_cache_hooks(klass, *reset_methods)
|
39
46
|
mod = self
|
@@ -55,11 +62,11 @@ Values are added to the cache in two ways:
|
|
55
62
|
# @!method read(locale, value, options = {})
|
56
63
|
# @option options [Boolean] cache *false* to disable cache.
|
57
64
|
def read(locale, **options)
|
58
|
-
return super(locale, options) if options.delete(:cache) == false
|
65
|
+
return super(locale, **options) if options.delete(:cache) == false
|
59
66
|
if cache.has_key?(locale)
|
60
67
|
cache[locale]
|
61
68
|
else
|
62
|
-
cache[locale] = super(locale, options)
|
69
|
+
cache[locale] = super(locale, **options)
|
63
70
|
end
|
64
71
|
end
|
65
72
|
|
@@ -90,7 +90,7 @@ The proc can accept zero to three arguments (see examples below)
|
|
90
90
|
# *false* to disable presence filter.
|
91
91
|
def read(locale, accessor_options = {})
|
92
92
|
default = accessor_options.has_key?(:default) ? accessor_options.delete(:default) : options[:default]
|
93
|
-
if (value = super(locale, accessor_options)).nil?
|
93
|
+
if (value = super(locale, **accessor_options)).nil?
|
94
94
|
Default[default, locale: locale, accessor_options: accessor_options, model: model, attribute: attribute]
|
95
95
|
else
|
96
96
|
value
|
@@ -47,7 +47,7 @@ the current locale was +nil+.
|
|
47
47
|
Mobility.locale = :ja
|
48
48
|
post.title
|
49
49
|
#=> "foo"
|
50
|
-
|
50
|
+
|
51
51
|
post.title = "bar"
|
52
52
|
post.title
|
53
53
|
#=> "bar"
|
@@ -144,15 +144,15 @@ the current locale was +nil+.
|
|
144
144
|
|
145
145
|
def define_read(fallbacks)
|
146
146
|
define_method :read do |locale, fallback: true, **options|
|
147
|
-
return super(locale, options) if !fallback || options[:locale]
|
147
|
+
return super(locale, **options) if !fallback || options[:locale]
|
148
148
|
|
149
149
|
locales = fallback == true ? fallbacks[locale] : [locale, *fallback]
|
150
150
|
locales.each do |fallback_locale|
|
151
|
-
value = super(fallback_locale, options)
|
151
|
+
value = super(fallback_locale, **options)
|
152
152
|
return value if Util.present?(value)
|
153
153
|
end
|
154
154
|
|
155
|
-
super(locale, options)
|
155
|
+
super(locale, **options)
|
156
156
|
end
|
157
157
|
end
|
158
158
|
|
@@ -24,14 +24,11 @@ model class is generated.
|
|
24
24
|
|
25
25
|
default true
|
26
26
|
|
27
|
-
requires :reader
|
28
|
-
requires :writer
|
29
|
-
|
30
27
|
# Apply fallthrough accessors plugin to attributes.
|
31
28
|
# @param [Translations] translations
|
32
29
|
# @param [Boolean] option
|
33
30
|
initialize_hook do
|
34
|
-
if options[:fallthrough_accessors]
|
31
|
+
if options[:fallthrough_accessors]
|
35
32
|
define_fallthrough_accessors(names)
|
36
33
|
end
|
37
34
|
end
|
@@ -47,9 +44,11 @@ model class is generated.
|
|
47
44
|
locale, suffix = $2.split('_')
|
48
45
|
locale = "#{locale}-#{suffix.upcase}" if suffix
|
49
46
|
if $4 == '=' # writer
|
50
|
-
|
47
|
+
kwargs = args[1].is_a?(Hash) ? args[1] : {}
|
48
|
+
public_send(attribute_method, args[0], **kwargs, locale: locale)
|
51
49
|
else # reader
|
52
|
-
|
50
|
+
kwargs = args[0].is_a?(Hash) ? args[0] : {}
|
51
|
+
public_send(attribute_method, **kwargs, locale: locale)
|
53
52
|
end
|
54
53
|
else
|
55
54
|
super(method_name, *args, &block)
|
@@ -19,9 +19,6 @@ available locales for a Rails application) will be used by default.
|
|
19
19
|
|
20
20
|
default true
|
21
21
|
|
22
|
-
requires :reader
|
23
|
-
requires :writer
|
24
|
-
|
25
22
|
# Apply locale accessors plugin to attributes.
|
26
23
|
# @param [Translations] translations
|
27
24
|
# @param [Boolean] option
|
@@ -30,8 +27,8 @@ available locales for a Rails application) will be used by default.
|
|
30
27
|
locales = Mobility.available_locales if locales == true
|
31
28
|
names.each do |name|
|
32
29
|
locales.each do |locale|
|
33
|
-
define_locale_reader(name, locale)
|
34
|
-
define_locale_writer(name, locale)
|
30
|
+
define_locale_reader(name, locale)
|
31
|
+
define_locale_writer(name, locale)
|
35
32
|
end
|
36
33
|
end
|
37
34
|
end
|
@@ -19,13 +19,13 @@ Defines attribute reader that delegates to +Mobility::Backend#read+.
|
|
19
19
|
class_eval <<-EOM, __FILE__, __LINE__ + 1
|
20
20
|
def #{name}(locale: nil, **options)
|
21
21
|
#{Reader.setup_source}
|
22
|
-
mobility_backends[:#{name}].read(locale, options)
|
22
|
+
mobility_backends[:#{name}].read(locale, **options)
|
23
23
|
end
|
24
24
|
EOM
|
25
25
|
class_eval <<-EOM, __FILE__, __LINE__ + 1
|
26
26
|
def #{name}?(locale: nil, **options)
|
27
27
|
#{Reader.setup_source}
|
28
|
-
mobility_backends[:#{name}].present?(locale, options)
|
28
|
+
mobility_backends[:#{name}].present?(locale, **options)
|
29
29
|
end
|
30
30
|
EOM
|
31
31
|
end
|
@@ -56,7 +56,7 @@ Automatically includes dirty plugin in model class when enabled.
|
|
56
56
|
if model.column_changes.has_key?(locale_accessor) && model.initial_values[locale_accessor] == value
|
57
57
|
super
|
58
58
|
[model.changed_columns, model.initial_values].each { |h| h.delete(locale_accessor) }
|
59
|
-
elsif read(locale, options.merge(fallback: false)) != value
|
59
|
+
elsif read(locale, **options.merge(fallback: false)) != value
|
60
60
|
model.will_change_column(locale_accessor)
|
61
61
|
super
|
62
62
|
end
|
@@ -19,7 +19,7 @@ Defines attribute writer that delegates to +Mobility::Backend#write+.
|
|
19
19
|
class_eval <<-EOM, __FILE__, __LINE__ + 1
|
20
20
|
def #{name}=(value, locale: nil, **options)
|
21
21
|
#{Writer.setup_source}
|
22
|
-
mobility_backends[:#{name}].write(locale, value, options)
|
22
|
+
mobility_backends[:#{name}].write(locale, value, **options)
|
23
23
|
end
|
24
24
|
EOM
|
25
25
|
end
|
data/lib/mobility/version.rb
CHANGED
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.
|
4
|
+
version: 1.0.0.beta1
|
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-
|
37
|
+
date: 2020-11-03 00:00:00.000000000 Z
|
38
38
|
dependencies:
|
39
39
|
- !ruby/object:Gem::Dependency
|
40
40
|
name: request_store
|
metadata.gz.sig
CHANGED
Binary file
|