mobility 1.0.0.beta2 → 1.0.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +3 -2
- data.tar.gz.sig +0 -0
- data/CHANGELOG.md +5 -0
- data/Gemfile.lock +19 -0
- data/README.md +4 -4
- data/lib/mobility.rb +60 -6
- data/lib/mobility/backends/active_record.rb +1 -1
- data/lib/mobility/backends/active_record/column.rb +1 -1
- data/lib/mobility/backends/active_record/container.rb +4 -4
- data/lib/mobility/backends/active_record/hstore.rb +3 -3
- data/lib/mobility/backends/active_record/json.rb +3 -3
- data/lib/mobility/backends/active_record/jsonb.rb +3 -3
- data/lib/mobility/backends/active_record/key_value.rb +27 -11
- data/lib/mobility/backends/active_record/table.rb +11 -6
- data/lib/mobility/backends/sequel.rb +32 -0
- data/lib/mobility/backends/sequel/container.rb +5 -3
- data/lib/mobility/backends/sequel/key_value.rb +79 -12
- data/lib/mobility/backends/sequel/pg_hash.rb +6 -6
- data/lib/mobility/backends/sequel/table.rb +18 -8
- data/lib/mobility/backends/table.rb +11 -6
- data/lib/mobility/plugins/active_record.rb +3 -0
- data/lib/mobility/plugins/active_record/backend.rb +2 -0
- data/lib/mobility/plugins/active_record/query.rb +2 -2
- data/lib/mobility/plugins/arel.rb +125 -0
- data/lib/mobility/plugins/arel/nodes.rb +15 -0
- data/lib/mobility/plugins/arel/nodes/pg_ops.rb +134 -0
- data/lib/mobility/plugins/sequel/dirty.rb +1 -1
- data/lib/mobility/version.rb +1 -1
- metadata +5 -17
- metadata.gz.sig +0 -0
- data/lib/mobility/active_record/model_translation.rb +0 -14
- data/lib/mobility/active_record/string_translation.rb +0 -10
- data/lib/mobility/active_record/text_translation.rb +0 -10
- data/lib/mobility/active_record/translation.rb +0 -14
- data/lib/mobility/arel.rb +0 -49
- data/lib/mobility/arel/nodes.rb +0 -13
- data/lib/mobility/arel/nodes/pg_ops.rb +0 -132
- data/lib/mobility/arel/visitor.rb +0 -61
- data/lib/mobility/sequel/column_changes.rb +0 -28
- data/lib/mobility/sequel/hash_initializer.rb +0 -21
- data/lib/mobility/sequel/model_translation.rb +0 -20
- data/lib/mobility/sequel/sql.rb +0 -16
- data/lib/mobility/sequel/string_translation.rb +0 -10
- data/lib/mobility/sequel/text_translation.rb +0 -10
- data/lib/mobility/sequel/translation.rb +0 -53
@@ -30,6 +30,38 @@ module Mobility
|
|
30
30
|
def prepare_dataset(dataset, _predicate, _locale)
|
31
31
|
dataset
|
32
32
|
end
|
33
|
+
|
34
|
+
# Forces Sequel to notice changes when Mobility setter method is
|
35
|
+
# called.
|
36
|
+
# TODO: Find a better way to do this.
|
37
|
+
def define_column_changes(mod, attributes, column_affix: "%s")
|
38
|
+
mod.class_eval do
|
39
|
+
attributes.each do |attribute|
|
40
|
+
define_method "#{attribute}=" do |value, **options|
|
41
|
+
if !options[:super] && send(attribute) != value
|
42
|
+
locale = options[:locale] || Mobility.locale
|
43
|
+
column = (column_affix % attribute).to_sym
|
44
|
+
attribute_with_locale = :"#{attribute}_#{Mobility.normalize_locale(locale)}"
|
45
|
+
@changed_columns = changed_columns | [column, attribute.to_sym, attribute_with_locale]
|
46
|
+
end
|
47
|
+
super(value, **options)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
# Initialize column value(s) by default to a hash.
|
54
|
+
# TODO: Find a better way to do this.
|
55
|
+
def define_hash_initializer(mod, columns)
|
56
|
+
mod.class_eval do
|
57
|
+
class_eval <<-EOM, __FILE__, __LINE__ + 1
|
58
|
+
def initialize_set(values)
|
59
|
+
#{columns.map { |c| "self[:#{c}] = {}" }.join(';')}
|
60
|
+
super
|
61
|
+
end
|
62
|
+
EOM
|
63
|
+
end
|
64
|
+
end
|
33
65
|
end
|
34
66
|
end
|
35
67
|
end
|
@@ -57,9 +57,11 @@ Implements the {Mobility::Backends::Container} backend for Sequel models.
|
|
57
57
|
end
|
58
58
|
end
|
59
59
|
|
60
|
+
backend = self
|
61
|
+
|
60
62
|
setup do |attributes, options|
|
61
63
|
column_name = options[:column_name]
|
62
|
-
|
64
|
+
mod = Module.new do
|
63
65
|
define_method :before_validation do
|
64
66
|
self[column_name].each do |k, v|
|
65
67
|
v.delete_if { |_locale, translation| Util.blank?(translation) }
|
@@ -68,8 +70,8 @@ Implements the {Mobility::Backends::Container} backend for Sequel models.
|
|
68
70
|
super()
|
69
71
|
end
|
70
72
|
end
|
71
|
-
include
|
72
|
-
|
73
|
+
include mod
|
74
|
+
backend.define_hash_initializer(mod, [column_name])
|
73
75
|
|
74
76
|
plugin :defaults_setter
|
75
77
|
attributes.each { |attribute| default_values[attribute.to_sym] = {} }
|
@@ -2,11 +2,6 @@
|
|
2
2
|
require "mobility/util"
|
3
3
|
require "mobility/backends/sequel"
|
4
4
|
require "mobility/backends/key_value"
|
5
|
-
require "mobility/sequel/column_changes"
|
6
|
-
require "mobility/sequel/hash_initializer"
|
7
|
-
require "mobility/sequel/string_translation"
|
8
|
-
require "mobility/sequel/text_translation"
|
9
|
-
require "mobility/sequel/sql"
|
10
5
|
|
11
6
|
module Mobility
|
12
7
|
module Backends
|
@@ -34,7 +29,7 @@ Implements the {Mobility::Backends::KeyValue} backend for Sequel models.
|
|
34
29
|
super
|
35
30
|
if type = options[:type]
|
36
31
|
options[:association_name] ||= :"#{options[:type]}_translations"
|
37
|
-
options[:class_name] ||=
|
32
|
+
options[:class_name] ||= const_get("#{type.capitalize}Translation")
|
38
33
|
end
|
39
34
|
options[:table_alias_affix] = "#{model_class}_%s_#{options[:association_name]}"
|
40
35
|
rescue NameError
|
@@ -43,7 +38,7 @@ Implements the {Mobility::Backends::KeyValue} backend for Sequel models.
|
|
43
38
|
# @!endgroup
|
44
39
|
|
45
40
|
def build_op(attr, locale)
|
46
|
-
|
41
|
+
QualifiedIdentifier.new(table_alias(attr, locale), :value, locale, self, attr)
|
47
42
|
end
|
48
43
|
|
49
44
|
# @param [Sequel::Dataset] dataset Dataset to prepare
|
@@ -75,7 +70,7 @@ Implements the {Mobility::Backends::KeyValue} backend for Sequel models.
|
|
75
70
|
case predicate
|
76
71
|
when Array
|
77
72
|
visit_collection(predicate, locale)
|
78
|
-
when
|
73
|
+
when QualifiedIdentifier
|
79
74
|
visit_sql_identifier(predicate, locale)
|
80
75
|
when ::Sequel::SQL::BooleanExpression
|
81
76
|
visit_boolean(predicate, locale)
|
@@ -128,6 +123,8 @@ Implements the {Mobility::Backends::KeyValue} backend for Sequel models.
|
|
128
123
|
end
|
129
124
|
end
|
130
125
|
|
126
|
+
backend = self
|
127
|
+
|
131
128
|
setup do |attributes, options|
|
132
129
|
association_name = options[:association_name]
|
133
130
|
translations_class = options[:class_name]
|
@@ -159,13 +156,14 @@ Implements the {Mobility::Backends::KeyValue} backend for Sequel models.
|
|
159
156
|
include callback_methods
|
160
157
|
|
161
158
|
include DestroyKeyValueTranslations
|
162
|
-
include
|
159
|
+
include(mod = Module.new)
|
160
|
+
backend.define_column_changes(mod, attributes)
|
163
161
|
end
|
164
162
|
|
165
163
|
# Returns translation for a given locale, or initializes one if none is present.
|
166
164
|
# @param [Symbol] locale
|
167
|
-
# @return [Mobility::Sequel::TextTranslation,Mobility::Sequel::StringTranslation]
|
168
|
-
def translation_for(locale,
|
165
|
+
# @return [Mobility::Backends::Sequel::KeyValue::TextTranslation,Mobility::Backends::Sequel::KeyValue::StringTranslation]
|
166
|
+
def translation_for(locale, **)
|
169
167
|
translation = model.send(association_name).find { |t| t.key == attribute && t.locale == locale.to_s }
|
170
168
|
translation ||= class_name.new(locale: locale, key: attribute)
|
171
169
|
translation
|
@@ -184,7 +182,7 @@ Implements the {Mobility::Backends::KeyValue} backend for Sequel models.
|
|
184
182
|
def after_destroy
|
185
183
|
super
|
186
184
|
[:string, :text].freeze.each do |type|
|
187
|
-
Mobility::Sequel.const_get("#{type.capitalize}Translation").
|
185
|
+
Mobility::Backends::Sequel::KeyValue.const_get("#{type.capitalize}Translation").
|
188
186
|
where(translatable_id: id, translatable_type: self.class.name).destroy
|
189
187
|
end
|
190
188
|
end
|
@@ -201,6 +199,75 @@ Implements the {Mobility::Backends::KeyValue} backend for Sequel models.
|
|
201
199
|
(model.send(association_name) + cache.values).uniq
|
202
200
|
end
|
203
201
|
end
|
202
|
+
|
203
|
+
class QualifiedIdentifier < ::Sequel::SQL::QualifiedIdentifier
|
204
|
+
attr_reader :backend_class, :locale, :attribute_name
|
205
|
+
|
206
|
+
def initialize(table, column, locale, backend_class, attribute_name)
|
207
|
+
@backend_class = backend_class
|
208
|
+
@locale = locale
|
209
|
+
@attribute_name = attribute_name || column
|
210
|
+
super(table, column)
|
211
|
+
end
|
212
|
+
end
|
213
|
+
|
214
|
+
module Translation
|
215
|
+
def self.included(base)
|
216
|
+
base.class_eval do
|
217
|
+
plugin :validation_helpers
|
218
|
+
|
219
|
+
# Paraphased from sequel_polymorphic gem
|
220
|
+
#
|
221
|
+
model = underscore(self.to_s)
|
222
|
+
plural_model = pluralize(model)
|
223
|
+
many_to_one :translatable,
|
224
|
+
reciprocal: plural_model.to_sym,
|
225
|
+
reciprocal_type: :many_to_one,
|
226
|
+
setter: (proc do |able_instance|
|
227
|
+
self[:translatable_id] = (able_instance.pk if able_instance)
|
228
|
+
self[:translatable_type] = (able_instance.class.name if able_instance)
|
229
|
+
end),
|
230
|
+
dataset: (proc do
|
231
|
+
translatable_type = send :translatable_type
|
232
|
+
translatable_id = send :translatable_id
|
233
|
+
return if translatable_type.nil? || translatable_id.nil?
|
234
|
+
klass = self.class.send(:constantize, translatable_type)
|
235
|
+
klass.where(klass.primary_key => translatable_id)
|
236
|
+
end),
|
237
|
+
eager_loader: (proc do |eo|
|
238
|
+
id_map = {}
|
239
|
+
eo[:rows].each do |model|
|
240
|
+
model_able_type = model.send :translatable_type
|
241
|
+
model_able_id = model.send :translatable_id
|
242
|
+
model.associations[:translatable] = nil
|
243
|
+
((id_map[model_able_type] ||= {})[model_able_id] ||= []) << model if !model_able_type.nil? && !model_able_id.nil?
|
244
|
+
end
|
245
|
+
id_map.each do |klass_name, id_map|
|
246
|
+
klass = constantize(camelize(klass_name))
|
247
|
+
klass.where(klass.primary_key=>id_map.keys).all do |related_obj|
|
248
|
+
id_map[related_obj.pk].each do |model|
|
249
|
+
model.associations[:translatable] = related_obj
|
250
|
+
end
|
251
|
+
end
|
252
|
+
end
|
253
|
+
end)
|
254
|
+
|
255
|
+
def validate
|
256
|
+
super
|
257
|
+
validates_presence [:locale, :key, :translatable_id, :translatable_type]
|
258
|
+
validates_unique [:locale, :key, :translatable_id, :translatable_type]
|
259
|
+
end
|
260
|
+
end
|
261
|
+
end
|
262
|
+
end
|
263
|
+
|
264
|
+
class TextTranslation < ::Sequel::Model(:mobility_text_translations)
|
265
|
+
include Translation
|
266
|
+
end
|
267
|
+
|
268
|
+
class StringTranslation < ::Sequel::Model(:mobility_string_translations)
|
269
|
+
include Translation
|
270
|
+
end
|
204
271
|
end
|
205
272
|
|
206
273
|
register_backend(:sequel_key_value, Sequel::KeyValue)
|
@@ -2,8 +2,6 @@
|
|
2
2
|
require "mobility/util"
|
3
3
|
require "mobility/backends/sequel"
|
4
4
|
require "mobility/backends/hash_valued"
|
5
|
-
require "mobility/sequel/column_changes"
|
6
|
-
require "mobility/sequel/hash_initializer"
|
7
5
|
|
8
6
|
module Mobility
|
9
7
|
module Backends
|
@@ -35,10 +33,12 @@ jsonb).
|
|
35
33
|
model[column_name.to_sym]
|
36
34
|
end
|
37
35
|
|
36
|
+
backend = self
|
37
|
+
|
38
38
|
setup do |attributes, options|
|
39
39
|
columns = attributes.map { |attribute| (options[:column_affix] % attribute).to_sym }
|
40
40
|
|
41
|
-
|
41
|
+
mod = Module.new do
|
42
42
|
define_method :before_validation do
|
43
43
|
columns.each do |column|
|
44
44
|
self[column].delete_if { |_, v| Util.blank?(v) }
|
@@ -46,9 +46,9 @@ jsonb).
|
|
46
46
|
super()
|
47
47
|
end
|
48
48
|
end
|
49
|
-
include
|
50
|
-
|
51
|
-
|
49
|
+
include mod
|
50
|
+
backend.define_hash_initializer(mod, columns)
|
51
|
+
backend.define_column_changes(mod, attributes, column_affix: options[:column_affix])
|
52
52
|
|
53
53
|
plugin :defaults_setter
|
54
54
|
columns.each { |column| default_values[column] = {} }
|
@@ -2,9 +2,6 @@
|
|
2
2
|
require "mobility/util"
|
3
3
|
require "mobility/backends/sequel"
|
4
4
|
require "mobility/backends/table"
|
5
|
-
require "mobility/sequel/column_changes"
|
6
|
-
require "mobility/sequel/model_translation"
|
7
|
-
require "mobility/sequel/sql"
|
8
5
|
|
9
6
|
module Mobility
|
10
7
|
module Backends
|
@@ -52,7 +49,7 @@ Implements the {Mobility::Backends::Table} backend for Sequel models.
|
|
52
49
|
# @param [Symbol] locale Locale
|
53
50
|
# @return [Sequel::SQL::QualifiedIdentifier]
|
54
51
|
def build_op(attr, locale)
|
55
|
-
::
|
52
|
+
::Sequel::SQL::QualifiedIdentifier.new(table_alias(locale), attr || :value)
|
56
53
|
end
|
57
54
|
|
58
55
|
# @param [Sequel::Dataset] dataset Dataset to prepare
|
@@ -83,7 +80,7 @@ Implements the {Mobility::Backends::Table} backend for Sequel models.
|
|
83
80
|
case predicate
|
84
81
|
when Array
|
85
82
|
visit_collection(predicate, locale)
|
86
|
-
when ::
|
83
|
+
when ::Sequel::SQL::QualifiedIdentifier
|
87
84
|
visit_sql_identifier(predicate, locale)
|
88
85
|
when ::Sequel::SQL::BooleanExpression
|
89
86
|
visit_boolean(predicate, locale)
|
@@ -119,6 +116,8 @@ Implements the {Mobility::Backends::Table} backend for Sequel models.
|
|
119
116
|
end
|
120
117
|
end
|
121
118
|
|
119
|
+
backend = self
|
120
|
+
|
122
121
|
setup do |attributes, options|
|
123
122
|
association_name = options[:association_name]
|
124
123
|
subclass_name = options[:subclass_name]
|
@@ -128,7 +127,7 @@ Implements the {Mobility::Backends::Table} backend for Sequel models.
|
|
128
127
|
const_get(subclass_name, false)
|
129
128
|
else
|
130
129
|
const_set(subclass_name, Class.new(::Sequel::Model(options[:table_name]))).tap do |klass|
|
131
|
-
klass.include
|
130
|
+
klass.include Translation
|
132
131
|
end
|
133
132
|
end
|
134
133
|
|
@@ -155,10 +154,11 @@ Implements the {Mobility::Backends::Table} backend for Sequel models.
|
|
155
154
|
end
|
156
155
|
include callback_methods
|
157
156
|
|
158
|
-
include
|
157
|
+
include(mod = Module.new)
|
158
|
+
backend.define_column_changes(mod, attributes)
|
159
159
|
end
|
160
160
|
|
161
|
-
def translation_for(locale,
|
161
|
+
def translation_for(locale, **)
|
162
162
|
translation = model.send(association_name).find { |t| t.locale == locale.to_s }
|
163
163
|
translation ||= translation_class.new(locale: locale)
|
164
164
|
translation
|
@@ -174,6 +174,16 @@ Implements the {Mobility::Backends::Table} backend for Sequel models.
|
|
174
174
|
end
|
175
175
|
end
|
176
176
|
|
177
|
+
module Translation
|
178
|
+
def self.included(base)
|
179
|
+
base.plugin :validation_helpers
|
180
|
+
end
|
181
|
+
|
182
|
+
def validate
|
183
|
+
super
|
184
|
+
validates_presence [:locale]
|
185
|
+
end
|
186
|
+
end
|
177
187
|
class CacheRequired < ::StandardError; end
|
178
188
|
end
|
179
189
|
|
@@ -10,8 +10,9 @@ Stores attribute translation as rows on a model-specific translation table
|
|
10
10
|
the table name for a model +Post+ with table +posts+ will be
|
11
11
|
+post_translations+, and the translation class will be +Post::Translation+. The
|
12
12
|
translation class is dynamically created when the backend is initialized on the
|
13
|
-
model class, and subclasses
|
14
|
-
|
13
|
+
model class, and subclasses
|
14
|
+
{Mobility::Backends::ActiveRecord::Table::Translation} (for AR models) or
|
15
|
+
inherits {Mobility::Backends::Sequel::Table::Translation} (for Sequel models).
|
15
16
|
|
16
17
|
The backend expects the translations table (+post_translations+) to have:
|
17
18
|
|
@@ -140,17 +141,21 @@ set.
|
|
140
141
|
end
|
141
142
|
|
142
143
|
def clear_cache
|
143
|
-
|
144
|
+
cache.clear
|
144
145
|
end
|
145
146
|
|
146
147
|
private
|
147
148
|
|
148
149
|
def cache
|
149
|
-
|
150
|
+
if model.instance_variable_defined?(cache_name)
|
151
|
+
model.instance_variable_get(cache_name)
|
152
|
+
else
|
153
|
+
model.instance_variable_set(cache_name, {})
|
154
|
+
end
|
150
155
|
end
|
151
156
|
|
152
|
-
def
|
153
|
-
|
157
|
+
def cache_name
|
158
|
+
@cache_name ||= :"@__mobility_#{association_name}_cache"
|
154
159
|
end
|
155
160
|
end
|
156
161
|
end
|
@@ -15,12 +15,15 @@ Plugin for ActiveRecord models.
|
|
15
15
|
module ActiveRecord
|
16
16
|
extend Plugin
|
17
17
|
|
18
|
+
requires :arel
|
19
|
+
|
18
20
|
requires :active_record_backend, include: :after
|
19
21
|
requires :active_record_dirty
|
20
22
|
requires :active_record_cache
|
21
23
|
requires :active_record_query
|
22
24
|
requires :active_record_uniqueness_validation
|
23
25
|
|
26
|
+
|
24
27
|
included_hook do |klass|
|
25
28
|
unless active_record_class?(klass)
|
26
29
|
name = klass.name || klass.to_s
|
@@ -199,7 +199,7 @@ enabled for any one attribute on the model.
|
|
199
199
|
# Builds a translated relation for a given opts hash and optional
|
200
200
|
# invert boolean.
|
201
201
|
def _build(scope, opts, locale, invert)
|
202
|
-
return yield if (mods =
|
202
|
+
return yield if (mods = translation_modules(scope)).empty?
|
203
203
|
|
204
204
|
keys, predicates = opts.keys.map(&:to_s), []
|
205
205
|
|
@@ -222,7 +222,7 @@ enabled for any one attribute on the model.
|
|
222
222
|
query_map[relation.where(predicates.inject(:and))]
|
223
223
|
end
|
224
224
|
|
225
|
-
def
|
225
|
+
def translation_modules(scope)
|
226
226
|
scope.model.ancestors.grep(::Mobility::Translations)
|
227
227
|
end
|
228
228
|
|
@@ -0,0 +1,125 @@
|
|
1
|
+
# frozen-string-literal: true
|
2
|
+
|
3
|
+
module Mobility
|
4
|
+
module Plugins
|
5
|
+
=begin
|
6
|
+
|
7
|
+
Plugin for Mobility Arel customizations. Basically used as a namespace to store
|
8
|
+
Arel-specific classes and modules.
|
9
|
+
|
10
|
+
=end
|
11
|
+
module Arel
|
12
|
+
extend Plugin
|
13
|
+
|
14
|
+
module MobilityExpressions
|
15
|
+
include ::Arel::Expressions
|
16
|
+
|
17
|
+
# @note This is necessary in order to ensure that when a translated
|
18
|
+
# attribute is selected with an alias using +AS+, the resulting
|
19
|
+
# expression can still be counted without blowing up.
|
20
|
+
#
|
21
|
+
# Extending +::Arel::Expressions+ is necessary to convince ActiveRecord
|
22
|
+
# that this node should not be stringified, which otherwise would
|
23
|
+
# result in garbage SQL.
|
24
|
+
#
|
25
|
+
# @see https://github.com/rails/rails/blob/847342c25c61acaea988430dc3ab66a82e3ed486/activerecord/lib/active_record/relation/calculations.rb#L261
|
26
|
+
def as(*)
|
27
|
+
super
|
28
|
+
.extend(::Arel::Expressions)
|
29
|
+
.extend(Countable)
|
30
|
+
end
|
31
|
+
|
32
|
+
module Countable
|
33
|
+
# @note This allows expressions with selected translated attributes to
|
34
|
+
# be counted.
|
35
|
+
def count(*args)
|
36
|
+
left.count(*args)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
class Attribute < ::Arel::Attributes::Attribute
|
42
|
+
include MobilityExpressions
|
43
|
+
|
44
|
+
attr_reader :backend_class
|
45
|
+
attr_reader :locale
|
46
|
+
attr_reader :attribute_name
|
47
|
+
|
48
|
+
def initialize(relation, column_name, locale, backend_class, attribute_name = nil)
|
49
|
+
@backend_class = backend_class
|
50
|
+
@locale = locale
|
51
|
+
@attribute_name = attribute_name || column_name
|
52
|
+
super(relation, column_name)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
class Visitor < ::Arel::Visitors::Visitor
|
57
|
+
INNER_JOIN = ::Arel::Nodes::InnerJoin
|
58
|
+
OUTER_JOIN = ::Arel::Nodes::OuterJoin
|
59
|
+
|
60
|
+
attr_reader :backend_class, :locale
|
61
|
+
|
62
|
+
def initialize(backend_class, locale)
|
63
|
+
super()
|
64
|
+
@backend_class, @locale = backend_class, locale
|
65
|
+
end
|
66
|
+
|
67
|
+
private
|
68
|
+
|
69
|
+
def visit(*args)
|
70
|
+
super
|
71
|
+
rescue TypeError
|
72
|
+
visit_default(*args)
|
73
|
+
end
|
74
|
+
|
75
|
+
def visit_collection(_objects)
|
76
|
+
raise NotImplementedError
|
77
|
+
end
|
78
|
+
alias :visit_Array :visit_collection
|
79
|
+
|
80
|
+
def visit_Arel_Nodes_Unary(object)
|
81
|
+
visit(object.expr)
|
82
|
+
end
|
83
|
+
|
84
|
+
def visit_Arel_Nodes_Binary(object)
|
85
|
+
visit_collection([object.left, object.right])
|
86
|
+
end
|
87
|
+
|
88
|
+
def visit_Arel_Nodes_Function(object)
|
89
|
+
visit_collection(object.expressions)
|
90
|
+
end
|
91
|
+
|
92
|
+
def visit_Arel_Nodes_Case(object)
|
93
|
+
visit_collection([object.case, object.conditions, object.default])
|
94
|
+
end
|
95
|
+
|
96
|
+
def visit_Arel_Nodes_And(object)
|
97
|
+
visit_Array(object.children)
|
98
|
+
end
|
99
|
+
|
100
|
+
def visit_Arel_Nodes_Node(object)
|
101
|
+
visit_default(object)
|
102
|
+
end
|
103
|
+
|
104
|
+
def visit_Arel_Attributes_Attribute(object)
|
105
|
+
visit_default(object)
|
106
|
+
end
|
107
|
+
|
108
|
+
def visit_default(_object)
|
109
|
+
nil
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
module Nodes
|
114
|
+
class Binary < ::Arel::Nodes::Binary; end
|
115
|
+
class Grouping < ::Arel::Nodes::Grouping; end
|
116
|
+
|
117
|
+
::Arel::Visitors::ToSql.class_eval do
|
118
|
+
alias :visit_Mobility_Plugins_Arel_Nodes_Grouping :visit_Arel_Nodes_Grouping
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
register_plugin(:arel, Arel)
|
124
|
+
end
|
125
|
+
end
|