diff --git a/lib/mobility/backends/active_record.rb b/lib/mobility/backends/active_record.rb index 9a1a59e85..a3187c79c 100644 --- a/lib/mobility/backends/active_record.rb +++ b/lib/mobility/backends/active_record.rb @@ -7,19 +7,6 @@ def self.included(backend_class) end module ClassMethods - def build_predicate(attr, locale, values, backend_options) - node = build_node(attr, locale, backend_options) - - nils, vals = Array.wrap(collapse(values)).uniq.partition(&:nil?) - return node.eq(nil) if vals.empty? - - vals = vals.map { |val| quote_value(val, backend_options) } - - predicate = vals.length == 1 ? node.eq(vals.first) : node.in(vals) - predicate = predicate.or(node.eq(nil)) unless nils.empty? - predicate - end - def quote_value(value, **) value.to_s end @@ -32,10 +19,6 @@ def add_scope(relation, _opts, _locale, _invert, _backend_options) relation end - def collapse(value) - value.is_a?(Array) ? value.uniq : value - end - def build_quoted(value) ::Arel::Nodes.build_quoted(value) end diff --git a/lib/mobility/backends/active_record/jsonb.rb b/lib/mobility/backends/active_record/jsonb.rb index a219108ca..2c062720d 100644 --- a/lib/mobility/backends/active_record/jsonb.rb +++ b/lib/mobility/backends/active_record/jsonb.rb @@ -31,7 +31,7 @@ class Jsonb < PgHash def self.build_node(attr, locale, model_class:, column_affix:, **) column_name = column_affix % attr - Node.new(model_class.arel_table[column_name], ::Arel::Nodes.build_quoted(locale)) + Node.new(model_class.arel_table[column_name], build_quoted(locale)) end def self.quote_value(value, **) diff --git a/lib/mobility/plugins/query.rb b/lib/mobility/plugins/query.rb index b27d0a52d..7eff3b2cc 100644 --- a/lib/mobility/plugins/query.rb +++ b/lib/mobility/plugins/query.rb @@ -75,9 +75,9 @@ def map(opts, locale, invert: false) attrs_opts = opts.slice(*i18n_keys) - backend_class = attrs.backend_class + predicate_builder = PredicateBuilder.new(attrs.backend_class) predicates += i18n_keys.map do |key| - backend_class.build_predicate(key, locale, opts.delete(key), attrs.options) + predicate_builder.build(key, locale, opts.delete(key), attrs.options) end [attrs, attrs_opts] @@ -91,7 +91,30 @@ def map(opts, locale, invert: false) end end - private_constant :WhereChain, :ClauseMapper + class PredicateBuilder + def initialize(backend_class) + @backend_class = backend_class + end + + def build(attr, locale, values, backend_options) + node = @backend_class.build_node(attr, locale, backend_options) + + nils, vals = Array.wrap(collapse(values)).uniq.partition(&:nil?) + return node.eq(nil) if vals.empty? + + vals = vals.map { |val| @backend_class.quote_value(val, backend_options) } + + predicate = vals.length == 1 ? node.eq(vals.first) : node.in(vals) + predicate = predicate.or(node.eq(nil)) unless nils.empty? + predicate + end + + def collapse(value) + value.is_a?(Array) ? value.uniq : value + end + end + + private_constant :WhereChain, :ClauseMapper, :PredicateBuilder end class FindByMethods < Module