mobility 1.1.3 → 1.2.3
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 +0 -0
- data/CHANGELOG.md +29 -3
- data/Gemfile.lock +30 -11
- data/README.md +1 -1
- data/lib/mobility/backend.rb +88 -26
- data/lib/mobility/backends/active_record/key_value.rb +68 -49
- data/lib/mobility/backends/sequel/container.rb +3 -5
- data/lib/mobility/backends/sequel/key_value.rb +63 -54
- data/lib/mobility/backends/sequel/pg_hash.rb +3 -5
- data/lib/mobility/backends/sequel/table.rb +3 -5
- data/lib/mobility/plugins/active_record/column_fallback.rb +66 -0
- data/lib/mobility/plugins/active_record.rb +2 -0
- data/lib/mobility/plugins/backend.rb +22 -4
- data/lib/mobility/plugins/column_fallback.rb +15 -0
- data/lib/mobility/plugins/fallbacks.rb +20 -25
- data/lib/mobility/plugins/sequel/column_fallback.rb +66 -0
- data/lib/mobility/plugins/sequel/query.rb +1 -1
- data/lib/mobility/plugins/sequel.rb +2 -0
- data/lib/mobility/version.rb +1 -1
- data.tar.gz.sig +0 -0
- metadata +5 -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: 7b94201a6b91ad2fff4818aa37fa4fd99df97944d98f3888af6b76f732f71658
|
4
|
+
data.tar.gz: 8be29d872e1488575253302daa13b46d5f065c5dd9aa35c526c0fd561ae478c5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a7afca6199b32df4105ad2bd55d33c6213677d424d6a4bb22e5d39e33b649de2e256a04b1f03e9c33d6374e5c4ec7858a7de9b2a0e190cc1a417da895981b7a0
|
7
|
+
data.tar.gz: 23ef1c7ca95c54872c5504a50af6c94116c94157586ba755a9ed57e6ca878647a1693460232840ed58c47f5807b6fd6c6db2283c397faf7a7e3402e93f675be3
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data/CHANGELOG.md
CHANGED
@@ -1,8 +1,32 @@
|
|
1
1
|
# Mobility Changelog
|
2
2
|
|
3
|
-
##
|
4
|
-
|
5
|
-
|
3
|
+
## 1.2
|
4
|
+
|
5
|
+
### 1.2.3
|
6
|
+
- Fix passing wrong options to super in fallbacks plugin
|
7
|
+
([#539](https://github.com/shioyama/mobility/pull/539))
|
8
|
+
|
9
|
+
### 1.2.2
|
10
|
+
- Make models work with `Marshal.dump`
|
11
|
+
([#532](https://github.com/shioyama/mobility/pull/532))
|
12
|
+
- Fix Sequel container op in Sequel
|
13
|
+
([#533](https://github.com/shioyama/mobility/pull/533))
|
14
|
+
- Simplify Fallbacks plugin
|
15
|
+
([#531](https://github.com/shioyama/mobility/pull/531))
|
16
|
+
|
17
|
+
### 1.2.1
|
18
|
+
- Refactor ColumnFallback plugin
|
19
|
+
([#530](https://github.com/shioyama/mobility/pull/530))
|
20
|
+
|
21
|
+
### 1.2.0
|
22
|
+
- Add ColumnFallback plugin
|
23
|
+
([#512](https://github.com/shioyama/mobility/pull/512))
|
24
|
+
- Fix Sequel querying on untranslated attributes in `i18n` block
|
25
|
+
([#529](https://github.com/shioyama/mobility/pull/529))
|
26
|
+
- Allow passing configured backend class as third argument to setup
|
27
|
+
([#528](https://github.com/shioyama/mobility/pull/528))
|
28
|
+
- Clearly distinguish backend classes from their configured subclasses
|
29
|
+
([#527](https://github.com/shioyama/mobility/pull/527))
|
6
30
|
|
7
31
|
## 1.1
|
8
32
|
|
@@ -10,6 +34,8 @@
|
|
10
34
|
- Do not swallow keyword args on ruby 3 in fallthrough accessors
|
11
35
|
([#520](https://github.com/shioyama/mobility/pull/520)) thanks
|
12
36
|
[doits](https://github.com/doits)!
|
37
|
+
- Assign blank values in pg hash backends
|
38
|
+
([#516](https://github.com/shioyama/mobility/pull/516))
|
13
39
|
|
14
40
|
### 1.1.2
|
15
41
|
- Check whether class responds to mobility_attribute?
|
data/Gemfile.lock
CHANGED
@@ -1,28 +1,44 @@
|
|
1
|
+
GIT
|
2
|
+
remote: https://github.com/rails/rails.git
|
3
|
+
revision: 0a751a021bfc0c71bb2a10ff8af9654c785c94f1
|
4
|
+
branch: main
|
5
|
+
specs:
|
6
|
+
activemodel (7.0.0.alpha2)
|
7
|
+
activesupport (= 7.0.0.alpha2)
|
8
|
+
activerecord (7.0.0.alpha2)
|
9
|
+
activemodel (= 7.0.0.alpha2)
|
10
|
+
activesupport (= 7.0.0.alpha2)
|
11
|
+
activesupport (7.0.0.alpha2)
|
12
|
+
concurrent-ruby (~> 1.0, >= 1.0.2)
|
13
|
+
i18n (>= 1.6, < 2)
|
14
|
+
minitest (>= 5.1)
|
15
|
+
tzinfo (~> 2.0)
|
16
|
+
|
1
17
|
PATH
|
2
18
|
remote: .
|
3
19
|
specs:
|
4
|
-
mobility (1.
|
20
|
+
mobility (1.3.0.alpha)
|
5
21
|
i18n (>= 0.6.10, < 2)
|
6
22
|
request_store (~> 1.0)
|
7
23
|
|
8
24
|
GEM
|
9
25
|
remote: https://rubygems.org/
|
10
26
|
specs:
|
11
|
-
benchmark-ips (2.
|
27
|
+
benchmark-ips (2.9.1)
|
12
28
|
byebug (11.1.3)
|
13
29
|
coderay (1.1.3)
|
14
|
-
concurrent-ruby (1.1.
|
30
|
+
concurrent-ruby (1.1.9)
|
15
31
|
database_cleaner (1.99.0)
|
16
32
|
diff-lcs (1.4.4)
|
17
|
-
ffi (1.15.
|
18
|
-
formatador (0.
|
19
|
-
guard (2.
|
33
|
+
ffi (1.15.4)
|
34
|
+
formatador (0.3.0)
|
35
|
+
guard (2.18.0)
|
20
36
|
formatador (>= 0.2.4)
|
21
37
|
listen (>= 2.7, < 4.0)
|
22
38
|
lumberjack (>= 1.0.12, < 2.0)
|
23
39
|
nenv (~> 0.1)
|
24
40
|
notiffany (~> 0.0)
|
25
|
-
pry (>= 0.
|
41
|
+
pry (>= 0.13.0)
|
26
42
|
shellany (~> 0.0)
|
27
43
|
thor (>= 0.18.1)
|
28
44
|
guard-compat (1.2.1)
|
@@ -32,11 +48,12 @@ GEM
|
|
32
48
|
rspec (>= 2.99.0, < 4.0)
|
33
49
|
i18n (1.8.10)
|
34
50
|
concurrent-ruby (~> 1.0)
|
35
|
-
listen (3.
|
51
|
+
listen (3.7.0)
|
36
52
|
rb-fsevent (~> 0.10, >= 0.10.3)
|
37
53
|
rb-inotify (~> 0.9, >= 0.9.10)
|
38
54
|
lumberjack (1.2.8)
|
39
55
|
method_source (1.0.0)
|
56
|
+
minitest (5.14.4)
|
40
57
|
nenv (0.3.0)
|
41
58
|
notiffany (0.1.3)
|
42
59
|
nenv (~> 0.1)
|
@@ -50,7 +67,7 @@ GEM
|
|
50
67
|
pry (~> 0.13.0)
|
51
68
|
rack (2.2.3)
|
52
69
|
rake (12.3.3)
|
53
|
-
rb-fsevent (0.
|
70
|
+
rb-fsevent (0.11.0)
|
54
71
|
rb-inotify (0.10.1)
|
55
72
|
ffi (~> 1.0)
|
56
73
|
request_store (1.5.0)
|
@@ -68,15 +85,18 @@ GEM
|
|
68
85
|
diff-lcs (>= 1.2.0, < 2.0)
|
69
86
|
rspec-support (~> 3.10.0)
|
70
87
|
rspec-support (3.10.2)
|
71
|
-
sequel (5.44.0)
|
72
88
|
shellany (0.0.1)
|
73
89
|
thor (1.1.0)
|
90
|
+
tzinfo (2.0.4)
|
91
|
+
concurrent-ruby (~> 1.0)
|
74
92
|
yard (0.9.26)
|
75
93
|
|
76
94
|
PLATFORMS
|
77
95
|
ruby
|
78
96
|
|
79
97
|
DEPENDENCIES
|
98
|
+
activerecord!
|
99
|
+
activesupport!
|
80
100
|
benchmark-ips
|
81
101
|
database_cleaner (~> 1.5, >= 1.5.3)
|
82
102
|
guard-rspec
|
@@ -85,7 +105,6 @@ DEPENDENCIES
|
|
85
105
|
pry-byebug
|
86
106
|
rake (~> 12, >= 12.2.1)
|
87
107
|
rspec (~> 3.0)
|
88
|
-
sequel (~> 5.0)
|
89
108
|
yard (~> 0.9.0)
|
90
109
|
|
91
110
|
BUNDLED WITH
|
data/README.md
CHANGED
data/lib/mobility/backend.rb
CHANGED
@@ -21,8 +21,8 @@ On top of this, a backend will normally:
|
|
21
21
|
corresponding to valid keys for configuring this backend.
|
22
22
|
- implement a +configure+ class method to apply any normalization to the
|
23
23
|
keys on the options hash included in +valid_keys+
|
24
|
-
- call the +setup+ method yielding attributes and options
|
25
|
-
model class
|
24
|
+
- call the +setup+ method yielding attributes and options (and optionally the
|
25
|
+
configured backend class) to configure the model class
|
26
26
|
|
27
27
|
@example Defining a Backend
|
28
28
|
class MyBackend
|
@@ -47,6 +47,13 @@ On top of this, a backend will normally:
|
|
47
47
|
setup do |attributes, options|
|
48
48
|
# Do something with attributes and options in context of model class.
|
49
49
|
end
|
50
|
+
|
51
|
+
# The block can optionally take the configured backend class as its third
|
52
|
+
# argument:
|
53
|
+
#
|
54
|
+
# setup do |attributes, options, backend_class|
|
55
|
+
# ...
|
56
|
+
# end
|
50
57
|
end
|
51
58
|
|
52
59
|
@see Mobility::Translations
|
@@ -70,6 +77,12 @@ On top of this, a backend will normally:
|
|
70
77
|
@attribute = args[1]
|
71
78
|
end
|
72
79
|
|
80
|
+
def ==(backend)
|
81
|
+
backend.class == self.class &&
|
82
|
+
backend.attribute == attribute &&
|
83
|
+
backend.model == model
|
84
|
+
end
|
85
|
+
|
73
86
|
# @!macro [new] backend_reader
|
74
87
|
# Gets the translated value for provided locale from configured backend.
|
75
88
|
# @param [Symbol] locale Locale to read
|
@@ -117,7 +130,6 @@ On top of this, a backend will normally:
|
|
117
130
|
# Extend included class with +setup+ method and other class methods
|
118
131
|
def self.included(base)
|
119
132
|
base.extend ClassMethods
|
120
|
-
base.singleton_class.attr_reader :options, :model_class
|
121
133
|
end
|
122
134
|
|
123
135
|
# Defines setup hooks for backend to customize model class.
|
@@ -136,9 +148,11 @@ On top of this, a backend will normally:
|
|
136
148
|
def setup &block
|
137
149
|
if @setup_block
|
138
150
|
setup_block = @setup_block
|
139
|
-
|
140
|
-
|
141
|
-
|
151
|
+
exec_setup_block = method(:exec_setup_block)
|
152
|
+
@setup_block = lambda do |attributes, options, backend_class|
|
153
|
+
[setup_block, block].each do |blk|
|
154
|
+
exec_setup_block.call(self, attributes, options, backend_class, &blk)
|
155
|
+
end
|
142
156
|
end
|
143
157
|
else
|
144
158
|
@setup_block = block
|
@@ -147,17 +161,6 @@ On top of this, a backend will normally:
|
|
147
161
|
|
148
162
|
def inherited(subclass)
|
149
163
|
subclass.instance_variable_set(:@setup_block, @setup_block)
|
150
|
-
subclass.instance_variable_set(:@options, @options)
|
151
|
-
subclass.instance_variable_set(:@model_class, @model_class)
|
152
|
-
end
|
153
|
-
|
154
|
-
# Call setup block on a class with attributes and options.
|
155
|
-
# @param model_class Class to be setup-ed
|
156
|
-
# @param [Array<String>] attribute_names
|
157
|
-
# @param [Hash] options
|
158
|
-
def setup_model(model_class, attribute_names)
|
159
|
-
return unless setup_block = @setup_block
|
160
|
-
model_class.class_exec(attribute_names, options, &setup_block)
|
161
164
|
end
|
162
165
|
|
163
166
|
# Build a subclass of this backend class for a given set of options
|
@@ -167,11 +170,7 @@ On top of this, a backend will normally:
|
|
167
170
|
# @param [Hash] options
|
168
171
|
# @return [Class] backend subclass
|
169
172
|
def build_subclass(model_class, options)
|
170
|
-
|
171
|
-
@model_class = model_class
|
172
|
-
configure(options) if respond_to?(:configure)
|
173
|
-
@options = options.freeze
|
174
|
-
end
|
173
|
+
ConfiguredBackend.build(self, model_class, options)
|
175
174
|
end
|
176
175
|
|
177
176
|
# Create instance and class methods to access value on options hash
|
@@ -188,10 +187,30 @@ On top of this, a backend will normally:
|
|
188
187
|
EOM
|
189
188
|
end
|
190
189
|
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
190
|
+
def options
|
191
|
+
raise_unconfigured!(:options)
|
192
|
+
end
|
193
|
+
|
194
|
+
def model_class
|
195
|
+
raise_unconfigured!(:model_class)
|
196
|
+
end
|
197
|
+
|
198
|
+
def setup_model(_model_class, _attributes)
|
199
|
+
raise_unconfigured!(:setup_model)
|
200
|
+
end
|
201
|
+
|
202
|
+
private
|
203
|
+
|
204
|
+
def raise_unconfigured!(method_name)
|
205
|
+
raise UnconfiguredError, "You are calling #{method_name} on an unconfigured backend class."
|
206
|
+
end
|
207
|
+
|
208
|
+
def exec_setup_block(model_class, *args, &block)
|
209
|
+
if block.arity == 3
|
210
|
+
model_class.class_exec(*args[0..2], &block)
|
211
|
+
else
|
212
|
+
model_class.class_exec(*args[0..1], &block)
|
213
|
+
end
|
195
214
|
end
|
196
215
|
end
|
197
216
|
|
@@ -204,5 +223,48 @@ On top of this, a backend will normally:
|
|
204
223
|
backend.write(locale, value, options)
|
205
224
|
end
|
206
225
|
end
|
226
|
+
|
227
|
+
class ConfiguredError < StandardError; end
|
228
|
+
class UnconfiguredError < StandardError; end
|
229
|
+
=begin
|
230
|
+
|
231
|
+
Module included in configured backend classes, which in addition to methods on
|
232
|
+
the parent backend class also have a +model_class+ and set of +options+.
|
233
|
+
|
234
|
+
=end
|
235
|
+
module ConfiguredBackend
|
236
|
+
def self.build(backend_class, model_class, options)
|
237
|
+
Class.new(backend_class) do
|
238
|
+
extend ConfiguredBackend
|
239
|
+
|
240
|
+
@model_class = model_class
|
241
|
+
configure(options) if respond_to?(:configure)
|
242
|
+
@options = options.freeze
|
243
|
+
end
|
244
|
+
end
|
245
|
+
|
246
|
+
def self.extended(klass)
|
247
|
+
klass.singleton_class.attr_reader :options, :model_class
|
248
|
+
end
|
249
|
+
|
250
|
+
# Call setup block on a class with attributes and options.
|
251
|
+
# @param model_class Class to be setup-ed
|
252
|
+
# @param [Array<String>] attribute_names
|
253
|
+
# @param [Hash] options
|
254
|
+
def setup_model(model_class, attribute_names)
|
255
|
+
return unless setup_block = @setup_block
|
256
|
+
exec_setup_block(model_class, attribute_names, options, self, &setup_block)
|
257
|
+
end
|
258
|
+
|
259
|
+
def inherited(_)
|
260
|
+
raise ConfiguredError, "Configured backends cannot be subclassed."
|
261
|
+
end
|
262
|
+
|
263
|
+
# Show subclassed backend class name, if it has one.
|
264
|
+
# @return [String]
|
265
|
+
def inspect
|
266
|
+
(name = superclass.name) ? "#<#{name}>" : super
|
267
|
+
end
|
268
|
+
end
|
207
269
|
end
|
208
270
|
end
|
@@ -65,6 +65,69 @@ Implements the {Mobility::Backends::KeyValue} backend for ActiveRecord models.
|
|
65
65
|
end
|
66
66
|
end
|
67
67
|
|
68
|
+
# Called from setup block. Can be overridden to customize behaviour.
|
69
|
+
def define_has_many_association(klass, attributes)
|
70
|
+
# Track all attributes for this association, so that we can limit the scope
|
71
|
+
# of keys for the association to only these attributes. We need to track the
|
72
|
+
# attributes assigned to the association in case this setup code is called
|
73
|
+
# multiple times, so we don't "forget" earlier attributes.
|
74
|
+
#
|
75
|
+
attrs_method_name = :"__#{association_name}_attributes"
|
76
|
+
association_attributes = (klass.instance_variable_get(:"@#{attrs_method_name}") || []) + attributes
|
77
|
+
klass.instance_variable_set(:"@#{attrs_method_name}", association_attributes)
|
78
|
+
|
79
|
+
b = self
|
80
|
+
|
81
|
+
klass.has_many association_name, ->{ where b.key_column => association_attributes },
|
82
|
+
as: belongs_to,
|
83
|
+
class_name: class_name.name,
|
84
|
+
inverse_of: belongs_to,
|
85
|
+
autosave: true
|
86
|
+
end
|
87
|
+
|
88
|
+
# Called from setup block. Can be overridden to customize behaviour.
|
89
|
+
def define_initialize_dup(klass)
|
90
|
+
b = self
|
91
|
+
module_name = "MobilityArKeyValue#{association_name.to_s.camelcase}"
|
92
|
+
unless const_defined?(module_name)
|
93
|
+
callback_methods = Module.new do
|
94
|
+
define_method :initialize_dup do |source|
|
95
|
+
super(source)
|
96
|
+
self.send("#{b.association_name}=", source.send(b.association_name).map(&:dup))
|
97
|
+
# Set inverse on associations
|
98
|
+
send(b.association_name).each do |translation|
|
99
|
+
translation.send(:"#{b.belongs_to}=", self)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
klass.include const_set(module_name, callback_methods)
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
# Called from setup block. Can be overridden to customize behaviour.
|
108
|
+
def define_before_save_callback(klass)
|
109
|
+
b = self
|
110
|
+
klass.before_save do
|
111
|
+
send(b.association_name).select { |t| t.send(b.value_column).blank? }.each do |translation|
|
112
|
+
send(b.association_name).destroy(translation)
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
# Called from setup block. Can be overridden to customize behaviour.
|
118
|
+
def define_after_destroy_callback(klass)
|
119
|
+
# Ensure we only call after destroy hook once per translations class
|
120
|
+
b = self
|
121
|
+
translation_classes = [class_name, *Mobility::Backends::ActiveRecord::KeyValue::Translation.descendants].uniq
|
122
|
+
klass.after_destroy do
|
123
|
+
@mobility_after_destroy_translation_classes = [] unless defined?(@mobility_after_destroy_translation_classes)
|
124
|
+
(translation_classes - @mobility_after_destroy_translation_classes).each do |translation_class|
|
125
|
+
translation_class.where(b.belongs_to => self).destroy_all
|
126
|
+
end
|
127
|
+
@mobility_after_destroy_translation_classes += translation_classes
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
68
131
|
private
|
69
132
|
|
70
133
|
def join_translations(relation, key, locale, join_type)
|
@@ -149,55 +212,11 @@ Implements the {Mobility::Backends::KeyValue} backend for ActiveRecord models.
|
|
149
212
|
end
|
150
213
|
end
|
151
214
|
|
152
|
-
setup do |attributes,
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
belongs_to = options[:belongs_to]
|
158
|
-
|
159
|
-
# Track all attributes for this association, so that we can limit the scope
|
160
|
-
# of keys for the association to only these attributes. We need to track the
|
161
|
-
# attributes assigned to the association in case this setup code is called
|
162
|
-
# multiple times, so we don't "forget" earlier attributes.
|
163
|
-
#
|
164
|
-
attrs_method_name = :"__#{association_name}_attributes"
|
165
|
-
association_attributes = (instance_variable_get(:"@#{attrs_method_name}") || []) + attributes
|
166
|
-
instance_variable_set(:"@#{attrs_method_name}", association_attributes)
|
167
|
-
|
168
|
-
has_many association_name, ->{ where key_column => association_attributes },
|
169
|
-
as: belongs_to,
|
170
|
-
class_name: translation_class.name,
|
171
|
-
inverse_of: belongs_to,
|
172
|
-
autosave: true
|
173
|
-
before_save do
|
174
|
-
send(association_name).select { |t| t.send(value_column).blank? }.each do |translation|
|
175
|
-
send(association_name).destroy(translation)
|
176
|
-
end
|
177
|
-
end
|
178
|
-
|
179
|
-
module_name = "MobilityArKeyValue#{association_name.to_s.camelcase}"
|
180
|
-
unless const_defined?(module_name)
|
181
|
-
callback_methods = Module.new do
|
182
|
-
define_method :initialize_dup do |source|
|
183
|
-
super(source)
|
184
|
-
self.send("#{association_name}=", source.send(association_name).map(&:dup))
|
185
|
-
# Set inverse on associations
|
186
|
-
send(association_name).each do |translation|
|
187
|
-
translation.send(:"#{belongs_to}=", self)
|
188
|
-
end
|
189
|
-
end
|
190
|
-
end
|
191
|
-
include const_set(module_name, callback_methods)
|
192
|
-
end
|
193
|
-
|
194
|
-
# Ensure we only call after destroy hook once per translations class
|
195
|
-
translation_classes = [translation_class, *Mobility::Backends::ActiveRecord::KeyValue::Translation.descendants].uniq
|
196
|
-
after_destroy do
|
197
|
-
@mobility_after_destroy_translation_classes = [] unless defined?(@mobility_after_destroy_translation_classes)
|
198
|
-
(translation_classes - @mobility_after_destroy_translation_classes).each { |klass| klass.where(belongs_to => self).destroy_all }
|
199
|
-
@mobility_after_destroy_translation_classes += translation_classes
|
200
|
-
end
|
215
|
+
setup do |attributes, _options, backend_class|
|
216
|
+
backend_class.define_has_many_association(self, attributes)
|
217
|
+
backend_class.define_initialize_dup(self)
|
218
|
+
backend_class.define_before_save_callback(self)
|
219
|
+
backend_class.define_after_destroy_callback(self)
|
201
220
|
end
|
202
221
|
|
203
222
|
# Returns translation for a given locale, or builds one if none is present.
|
@@ -57,9 +57,7 @@ Implements the {Mobility::Backends::Container} backend for Sequel models.
|
|
57
57
|
end
|
58
58
|
end
|
59
59
|
|
60
|
-
|
61
|
-
|
62
|
-
setup do |attributes, options|
|
60
|
+
setup do |attributes, options, backend_class|
|
63
61
|
column_name = options[:column_name]
|
64
62
|
mod = Module.new do
|
65
63
|
define_method :before_validation do
|
@@ -71,7 +69,7 @@ Implements the {Mobility::Backends::Container} backend for Sequel models.
|
|
71
69
|
end
|
72
70
|
end
|
73
71
|
include mod
|
74
|
-
|
72
|
+
backend_class.define_hash_initializer(mod, [column_name])
|
75
73
|
|
76
74
|
plugin :defaults_setter
|
77
75
|
attributes.each { |attribute| default_values[attribute.to_sym] = {} }
|
@@ -102,7 +100,7 @@ Implements the {Mobility::Backends::Container} backend for Sequel models.
|
|
102
100
|
# @return [Mobility::Backends::Sequel::Container::JSONOp,Mobility::Backends::Sequel::Container::JSONBOp]
|
103
101
|
def self.build_op(attr, locale)
|
104
102
|
klass = const_get("#{options[:column_type].upcase}Op")
|
105
|
-
klass.new(klass.new(column_name.to_sym)
|
103
|
+
klass.new(klass.new(column_name.to_sym).get(locale.to_s)).get_text(attr)
|
106
104
|
end
|
107
105
|
|
108
106
|
class JSONOp < ::Sequel::Postgres::JSONOp; end
|
@@ -51,6 +51,63 @@ Implements the {Mobility::Backends::KeyValue} backend for Sequel models.
|
|
51
51
|
end
|
52
52
|
end
|
53
53
|
|
54
|
+
# Called from setup block. Can be overridden to customize behaviour.
|
55
|
+
def define_one_to_many_association(klass, attributes)
|
56
|
+
belongs_to_id = :"#{belongs_to}_id"
|
57
|
+
belongs_to_type = :"#{belongs_to}_type"
|
58
|
+
|
59
|
+
# Track all attributes for this association, so that we can limit the scope
|
60
|
+
# of keys for the association to only these attributes. We need to track the
|
61
|
+
# attributes assigned to the association in case this setup code is called
|
62
|
+
# multiple times, so we don't "forget" earlier attributes.
|
63
|
+
#
|
64
|
+
attrs_method_name = :"#{association_name}_attributes"
|
65
|
+
association_attributes = (klass.instance_variable_get(:"@#{attrs_method_name}") || []) + attributes
|
66
|
+
klass.instance_variable_set(:"@#{attrs_method_name}", association_attributes)
|
67
|
+
|
68
|
+
klass.one_to_many association_name,
|
69
|
+
reciprocal: belongs_to,
|
70
|
+
key: belongs_to_id,
|
71
|
+
reciprocal_type: :one_to_many,
|
72
|
+
conditions: { belongs_to_type => klass.to_s, key_column => association_attributes },
|
73
|
+
adder: proc { |translation| translation.update(belongs_to_id => pk, belongs_to_type => self.class.to_s) },
|
74
|
+
remover: proc { |translation| translation.update(belongs_to_id => nil, belongs_to_type => nil) },
|
75
|
+
clearer: proc { send_(:"#{association_name}_dataset").update(belongs_to_id => nil, belongs_to_type => nil) },
|
76
|
+
class: class_name
|
77
|
+
end
|
78
|
+
|
79
|
+
# Called from setup block. Can be overridden to customize behaviour.
|
80
|
+
def define_save_callbacks(klass, attributes)
|
81
|
+
b = self
|
82
|
+
callback_methods = Module.new do
|
83
|
+
define_method :before_save do
|
84
|
+
super()
|
85
|
+
send(b.association_name).select { |t| attributes.include?(t.__send__(b.key_column)) && Util.blank?(t.__send__(b.value_column)) }.each(&:destroy)
|
86
|
+
end
|
87
|
+
define_method :after_save do
|
88
|
+
super()
|
89
|
+
attributes.each { |attribute| mobility_backends[attribute].save_translations }
|
90
|
+
end
|
91
|
+
end
|
92
|
+
klass.include callback_methods
|
93
|
+
end
|
94
|
+
|
95
|
+
# Called from setup block. Can be overridden to customize behaviour.
|
96
|
+
def define_after_destroy_callback(klass)
|
97
|
+
# Clean up *all* leftover translations of this model, only once.
|
98
|
+
b = self
|
99
|
+
translation_classes = [class_name, *Mobility::Backends::Sequel::KeyValue::Translation.descendants].uniq
|
100
|
+
klass.define_method :after_destroy do
|
101
|
+
super()
|
102
|
+
|
103
|
+
@mobility_after_destroy_translation_classes = [] unless defined?(@mobility_after_destroy_translation_classes)
|
104
|
+
(translation_classes - @mobility_after_destroy_translation_classes).each do |translation_class|
|
105
|
+
translation_class.where(:"#{b.belongs_to}_id" => id, :"#{b.belongs_to}_type" => self.class.name).destroy
|
106
|
+
end
|
107
|
+
@mobility_after_destroy_translation_classes += translation_classes
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
54
111
|
private
|
55
112
|
|
56
113
|
def join_translations(dataset, attr, locale, join_type)
|
@@ -74,7 +131,7 @@ Implements the {Mobility::Backends::KeyValue} backend for Sequel models.
|
|
74
131
|
visit_sql_identifier(predicate, locale)
|
75
132
|
when ::Sequel::SQL::BooleanExpression
|
76
133
|
visit_boolean(predicate, locale)
|
77
|
-
when ::Sequel::SQL::
|
134
|
+
when ::Sequel::SQL::ComplexExpression
|
78
135
|
visit(predicate.args, locale)
|
79
136
|
else
|
80
137
|
{}
|
@@ -123,61 +180,13 @@ Implements the {Mobility::Backends::KeyValue} backend for Sequel models.
|
|
123
180
|
end
|
124
181
|
end
|
125
182
|
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
translation_class = options[:class_name]
|
131
|
-
key_column = options[:key_column]
|
132
|
-
value_column = options[:value_column]
|
133
|
-
belongs_to = options[:belongs_to]
|
134
|
-
belongs_to_id = :"#{belongs_to}_id"
|
135
|
-
belongs_to_type = :"#{belongs_to}_type"
|
136
|
-
|
137
|
-
# Track all attributes for this association, so that we can limit the scope
|
138
|
-
# of keys for the association to only these attributes. We need to track the
|
139
|
-
# attributes assigned to the association in case this setup code is called
|
140
|
-
# multiple times, so we don't "forget" earlier attributes.
|
141
|
-
#
|
142
|
-
attrs_method_name = :"#{association_name}_attributes"
|
143
|
-
association_attributes = (instance_variable_get(:"@#{attrs_method_name}") || []) + attributes
|
144
|
-
instance_variable_set(:"@#{attrs_method_name}", association_attributes)
|
145
|
-
|
146
|
-
one_to_many association_name,
|
147
|
-
reciprocal: belongs_to,
|
148
|
-
key: belongs_to_id,
|
149
|
-
reciprocal_type: :one_to_many,
|
150
|
-
conditions: { belongs_to_type => self.to_s, key_column => association_attributes },
|
151
|
-
adder: proc { |translation| translation.update(belongs_to_id => pk, belongs_to_type => self.class.to_s) },
|
152
|
-
remover: proc { |translation| translation.update(belongs_to_id => nil, belongs_to_type => nil) },
|
153
|
-
clearer: proc { send_(:"#{association_name}_dataset").update(belongs_to_id => nil, belongs_to_type => nil) },
|
154
|
-
class: translation_class
|
155
|
-
|
156
|
-
callback_methods = Module.new do
|
157
|
-
define_method :before_save do
|
158
|
-
super()
|
159
|
-
send(association_name).select { |t| attributes.include?(t.__send__(key_column)) && Util.blank?(t.__send__(value_column)) }.each(&:destroy)
|
160
|
-
end
|
161
|
-
define_method :after_save do
|
162
|
-
super()
|
163
|
-
attributes.each { |attribute| mobility_backends[attribute].save_translations }
|
164
|
-
end
|
165
|
-
end
|
166
|
-
include callback_methods
|
167
|
-
|
168
|
-
# Clean up *all* leftover translations of this model, only once.
|
169
|
-
translation_classes = [translation_class, *Mobility::Backends::Sequel::KeyValue::Translation.descendants].uniq
|
170
|
-
define_method :after_destroy do
|
171
|
-
super()
|
183
|
+
setup do |attributes, _options, backend_class|
|
184
|
+
backend_class.define_one_to_many_association(self, attributes)
|
185
|
+
backend_class.define_save_callbacks(self, attributes)
|
186
|
+
backend_class.define_after_destroy_callback(self)
|
172
187
|
|
173
|
-
@mobility_after_destroy_translation_classes = [] unless defined?(@mobility_after_destroy_translation_classes)
|
174
|
-
(translation_classes - @mobility_after_destroy_translation_classes).each do |klass|
|
175
|
-
klass.where(belongs_to_id => id, belongs_to_type => self.class.name).destroy
|
176
|
-
end
|
177
|
-
@mobility_after_destroy_translation_classes += translation_classes
|
178
|
-
end
|
179
188
|
include(mod = Module.new)
|
180
|
-
|
189
|
+
backend_class.define_column_changes(mod, attributes)
|
181
190
|
end
|
182
191
|
|
183
192
|
# Returns translation for a given locale, or initializes one if none is present.
|
@@ -33,9 +33,7 @@ jsonb).
|
|
33
33
|
model[column_name.to_sym]
|
34
34
|
end
|
35
35
|
|
36
|
-
|
37
|
-
|
38
|
-
setup do |attributes, options|
|
36
|
+
setup do |attributes, options, backend_class|
|
39
37
|
columns = attributes.map { |attribute| (options[:column_affix] % attribute).to_sym }
|
40
38
|
|
41
39
|
mod = Module.new do
|
@@ -47,8 +45,8 @@ jsonb).
|
|
47
45
|
end
|
48
46
|
end
|
49
47
|
include mod
|
50
|
-
|
51
|
-
|
48
|
+
backend_class.define_hash_initializer(mod, columns)
|
49
|
+
backend_class.define_column_changes(mod, attributes, column_affix: options[:column_affix])
|
52
50
|
|
53
51
|
plugin :defaults_setter
|
54
52
|
columns.each { |column| default_values[column] = {} }
|
@@ -84,7 +84,7 @@ Implements the {Mobility::Backends::Table} backend for Sequel models.
|
|
84
84
|
visit_sql_identifier(predicate, locale)
|
85
85
|
when ::Sequel::SQL::BooleanExpression
|
86
86
|
visit_boolean(predicate, locale)
|
87
|
-
when ::Sequel::SQL::
|
87
|
+
when ::Sequel::SQL::ComplexExpression
|
88
88
|
visit(predicate.args, locale)
|
89
89
|
else
|
90
90
|
nil
|
@@ -116,9 +116,7 @@ Implements the {Mobility::Backends::Table} backend for Sequel models.
|
|
116
116
|
end
|
117
117
|
end
|
118
118
|
|
119
|
-
|
120
|
-
|
121
|
-
setup do |attributes, options|
|
119
|
+
setup do |attributes, options, backend_class|
|
122
120
|
association_name = options[:association_name]
|
123
121
|
subclass_name = options[:subclass_name]
|
124
122
|
|
@@ -155,7 +153,7 @@ Implements the {Mobility::Backends::Table} backend for Sequel models.
|
|
155
153
|
include callback_methods
|
156
154
|
|
157
155
|
include(mod = Module.new)
|
158
|
-
|
156
|
+
backend_class.define_column_changes(mod, attributes)
|
159
157
|
end
|
160
158
|
|
161
159
|
def translation_for(locale, **)
|
@@ -0,0 +1,66 @@
|
|
1
|
+
# frozen-string-literal: true
|
2
|
+
|
3
|
+
module Mobility
|
4
|
+
module Plugins
|
5
|
+
=begin
|
6
|
+
|
7
|
+
Plugin to use an original column for a given locale, and otherwise use the backend.
|
8
|
+
|
9
|
+
=end
|
10
|
+
module ActiveRecord
|
11
|
+
module ColumnFallback
|
12
|
+
extend Plugin
|
13
|
+
|
14
|
+
requires :column_fallback, include: false
|
15
|
+
|
16
|
+
included_hook do |_, backend_class|
|
17
|
+
backend_class.include BackendInstanceMethods
|
18
|
+
backend_class.extend BackendClassMethods
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.use_column_fallback?(options, locale)
|
22
|
+
case column_fallback = options[:column_fallback]
|
23
|
+
when TrueClass
|
24
|
+
locale == I18n.default_locale
|
25
|
+
when Array
|
26
|
+
column_fallback.include?(locale)
|
27
|
+
when Proc
|
28
|
+
column_fallback.call(locale)
|
29
|
+
else
|
30
|
+
false
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
module BackendInstanceMethods
|
35
|
+
def read(locale, **)
|
36
|
+
if ColumnFallback.use_column_fallback?(options, locale)
|
37
|
+
model.read_attribute(attribute)
|
38
|
+
else
|
39
|
+
super
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def write(locale, value, **)
|
44
|
+
if ColumnFallback.use_column_fallback?(options, locale)
|
45
|
+
model.send(:write_attribute, attribute, value)
|
46
|
+
else
|
47
|
+
super
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
module BackendClassMethods
|
53
|
+
def build_node(attr, locale)
|
54
|
+
if ColumnFallback.use_column_fallback?(options, locale)
|
55
|
+
model_class.arel_table[attr]
|
56
|
+
else
|
57
|
+
super
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
register_plugin(:active_record_column_fallback, ActiveRecord::ColumnFallback)
|
65
|
+
end
|
66
|
+
end
|
@@ -4,6 +4,7 @@ require_relative "./active_record/dirty"
|
|
4
4
|
require_relative "./active_record/cache"
|
5
5
|
require_relative "./active_record/query"
|
6
6
|
require_relative "./active_record/uniqueness_validation"
|
7
|
+
require_relative "./active_record/column_fallback"
|
7
8
|
|
8
9
|
module Mobility
|
9
10
|
=begin
|
@@ -24,6 +25,7 @@ dirty for active_record_dirty) is also enabled.
|
|
24
25
|
requires :active_record_cache
|
25
26
|
requires :active_record_query
|
26
27
|
requires :active_record_uniqueness_validation
|
28
|
+
requires :active_record_column_fallback
|
27
29
|
|
28
30
|
|
29
31
|
included_hook do |klass|
|
@@ -114,15 +114,33 @@ Defines:
|
|
114
114
|
defaults[key] = [backend, backend_options] if backend
|
115
115
|
end
|
116
116
|
|
117
|
+
class MobilityBackends < Hash
|
118
|
+
def initialize(model)
|
119
|
+
@model = model
|
120
|
+
super()
|
121
|
+
end
|
122
|
+
|
123
|
+
def [](name)
|
124
|
+
return fetch(name) if has_key?(name)
|
125
|
+
return self[name.to_sym] if String === name
|
126
|
+
self[name] = @model.class.mobility_backend_class(name).new(@model, name.to_s)
|
127
|
+
end
|
128
|
+
|
129
|
+
def marshal_dump
|
130
|
+
@model
|
131
|
+
end
|
132
|
+
|
133
|
+
def marshal_load(model)
|
134
|
+
@model = model
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
117
138
|
module InstanceMethods
|
118
139
|
# Return a new backend for an attribute name.
|
119
140
|
# @return [Hash] Hash of attribute names and backend instances
|
120
141
|
# @api private
|
121
142
|
def mobility_backends
|
122
|
-
@mobility_backends ||=
|
123
|
-
next hash[name.to_sym] if String === name
|
124
|
-
hash[name] = self.class.mobility_backend_class(name).new(self, name.to_s)
|
125
|
-
end
|
143
|
+
@mobility_backends ||= MobilityBackends.new(self)
|
126
144
|
end
|
127
145
|
|
128
146
|
def initialize_dup(other)
|
@@ -117,8 +117,10 @@ the current locale was +nil+.
|
|
117
117
|
# Applies fallbacks plugin to attributes. Completely disables fallbacks
|
118
118
|
# on model if option is +false+.
|
119
119
|
included_hook do |_, backend_class|
|
120
|
-
|
121
|
-
|
120
|
+
backend_class.include(BackendInstanceMethods) unless options[:fallbacks] == false
|
121
|
+
# This is weird. We need to find a better way to allow customization of
|
122
|
+
# rarely-customized code like this.
|
123
|
+
backend_class.define_method(:generate_fallbacks, &method(:generate_fallbacks))
|
122
124
|
end
|
123
125
|
|
124
126
|
private
|
@@ -134,33 +136,26 @@ the current locale was +nil+.
|
|
134
136
|
end
|
135
137
|
end
|
136
138
|
|
137
|
-
|
138
|
-
def
|
139
|
-
|
140
|
-
define_read(convert_option_to_fallbacks(fallbacks_option))
|
141
|
-
end
|
142
|
-
|
143
|
-
private
|
144
|
-
|
145
|
-
def define_read(fallbacks)
|
146
|
-
define_method :read do |locale, fallback: true, **options|
|
147
|
-
return super(locale, **options) if !fallback || options[:locale]
|
139
|
+
module BackendInstanceMethods
|
140
|
+
def read(locale, fallback: true, **kwargs)
|
141
|
+
return super(locale, **kwargs) if !fallback || kwargs[:locale]
|
148
142
|
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
end
|
154
|
-
|
155
|
-
super(locale, **options)
|
143
|
+
locales = fallback == true ? fallbacks[locale] : [locale, *fallback]
|
144
|
+
locales.each do |fallback_locale|
|
145
|
+
value = super(fallback_locale, **kwargs)
|
146
|
+
return value if Util.present?(value)
|
156
147
|
end
|
148
|
+
|
149
|
+
super(locale, **kwargs)
|
157
150
|
end
|
158
151
|
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
152
|
+
private
|
153
|
+
|
154
|
+
def fallbacks
|
155
|
+
if options[:fallbacks].is_a?(Hash)
|
156
|
+
generate_fallbacks(options[:fallbacks])
|
157
|
+
elsif options[:fallbacks] == true
|
158
|
+
generate_fallbacks({})
|
164
159
|
else
|
165
160
|
::Hash.new { [] }
|
166
161
|
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
# frozen-string-literal: true
|
2
|
+
|
3
|
+
module Mobility
|
4
|
+
=begin
|
5
|
+
|
6
|
+
Plugin to use an original column for a given locale, and otherwise use the backend.
|
7
|
+
|
8
|
+
=end
|
9
|
+
module Plugins
|
10
|
+
module Sequel
|
11
|
+
module ColumnFallback
|
12
|
+
extend Plugin
|
13
|
+
|
14
|
+
requires :column_fallback, include: false
|
15
|
+
|
16
|
+
included_hook do |_, backend_class|
|
17
|
+
backend_class.include BackendInstanceMethods
|
18
|
+
backend_class.extend BackendClassMethods
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.use_column_fallback?(options, locale)
|
22
|
+
case column_fallback = options[:column_fallback]
|
23
|
+
when TrueClass
|
24
|
+
locale == I18n.default_locale
|
25
|
+
when Array
|
26
|
+
column_fallback.include?(locale)
|
27
|
+
when Proc
|
28
|
+
column_fallback.call(locale)
|
29
|
+
else
|
30
|
+
false
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
module BackendInstanceMethods
|
35
|
+
def read(locale, **)
|
36
|
+
if ColumnFallback.use_column_fallback?(options, locale)
|
37
|
+
model[attribute.to_sym]
|
38
|
+
else
|
39
|
+
super
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def write(locale, value, **)
|
44
|
+
if ColumnFallback.use_column_fallback?(options, locale)
|
45
|
+
model[attribute.to_sym] = value
|
46
|
+
else
|
47
|
+
super
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
module BackendClassMethods
|
53
|
+
def build_op(attr, locale)
|
54
|
+
if ColumnFallback.use_column_fallback?(options, locale)
|
55
|
+
::Sequel::SQL::QualifiedIdentifier.new(model_class.table_name, attr.to_sym)
|
56
|
+
else
|
57
|
+
super
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
register_plugin(:sequel_column_fallback, Sequel::ColumnFallback)
|
65
|
+
end
|
66
|
+
end
|
@@ -61,7 +61,7 @@ ActiveRecord query plugin.
|
|
61
61
|
locale = args[0] || @global_locale
|
62
62
|
@locales |= [locale]
|
63
63
|
@model_class.mobility_backend_class(m).build_op(m.to_s, locale)
|
64
|
-
elsif @model_class.columns.include?(m
|
64
|
+
elsif @model_class.columns.include?(m)
|
65
65
|
::Sequel::SQL::QualifiedIdentifier.new(@model_class.table_name, m)
|
66
66
|
else
|
67
67
|
super
|
@@ -9,6 +9,7 @@ require_relative "./sequel/backend"
|
|
9
9
|
require_relative "./sequel/dirty"
|
10
10
|
require_relative "./sequel/cache"
|
11
11
|
require_relative "./sequel/query"
|
12
|
+
require_relative "./sequel/column_fallback"
|
12
13
|
|
13
14
|
module Mobility
|
14
15
|
module Plugins
|
@@ -26,6 +27,7 @@ for sequel_dirty) is also enabled.
|
|
26
27
|
requires :sequel_dirty
|
27
28
|
requires :sequel_cache
|
28
29
|
requires :sequel_query
|
30
|
+
requires :sequel_column_fallback
|
29
31
|
|
30
32
|
included_hook do |klass|
|
31
33
|
unless sequel_class?(klass)
|
data/lib/mobility/version.rb
CHANGED
data.tar.gz.sig
CHANGED
Binary file
|
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.
|
4
|
+
version: 1.2.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Chris Salzberg
|
@@ -34,7 +34,7 @@ cert_chain:
|
|
34
34
|
eBMcZq0d1tbtv1M1UXND9mOfhLZ31YvoSTPkrJiRpljUNgD0+ugelnr1/5X/9k8y
|
35
35
|
J9QOd3C5jpSShf/HMvpJnFuSYFm19cH9GrHjvw==
|
36
36
|
-----END CERTIFICATE-----
|
37
|
-
date: 2021-
|
37
|
+
date: 2021-10-25 00:00:00.000000000 Z
|
38
38
|
dependencies:
|
39
39
|
- !ruby/object:Gem::Dependency
|
40
40
|
name: request_store
|
@@ -198,6 +198,7 @@ files:
|
|
198
198
|
- lib/mobility/plugins/active_record.rb
|
199
199
|
- lib/mobility/plugins/active_record/backend.rb
|
200
200
|
- lib/mobility/plugins/active_record/cache.rb
|
201
|
+
- lib/mobility/plugins/active_record/column_fallback.rb
|
201
202
|
- lib/mobility/plugins/active_record/dirty.rb
|
202
203
|
- lib/mobility/plugins/active_record/query.rb
|
203
204
|
- lib/mobility/plugins/active_record/uniqueness_validation.rb
|
@@ -209,6 +210,7 @@ files:
|
|
209
210
|
- lib/mobility/plugins/backend.rb
|
210
211
|
- lib/mobility/plugins/backend_reader.rb
|
211
212
|
- lib/mobility/plugins/cache.rb
|
213
|
+
- lib/mobility/plugins/column_fallback.rb
|
212
214
|
- lib/mobility/plugins/default.rb
|
213
215
|
- lib/mobility/plugins/dirty.rb
|
214
216
|
- lib/mobility/plugins/fallbacks.rb
|
@@ -220,6 +222,7 @@ files:
|
|
220
222
|
- lib/mobility/plugins/sequel.rb
|
221
223
|
- lib/mobility/plugins/sequel/backend.rb
|
222
224
|
- lib/mobility/plugins/sequel/cache.rb
|
225
|
+
- lib/mobility/plugins/sequel/column_fallback.rb
|
223
226
|
- lib/mobility/plugins/sequel/dirty.rb
|
224
227
|
- lib/mobility/plugins/sequel/query.rb
|
225
228
|
- lib/mobility/plugins/writer.rb
|
metadata.gz.sig
CHANGED
Binary file
|