Skip to content

Commit

Permalink
Refactor PredicateBuilder
Browse files Browse the repository at this point in the history
  • Loading branch information
shioyama committed Apr 29, 2018
1 parent f5678d8 commit 5f106a2
Showing 1 changed file with 23 additions and 11 deletions.
34 changes: 23 additions & 11 deletions lib/mobility/plugins/query.rb
Original file line number Diff line number Diff line change
Expand Up @@ -75,34 +75,41 @@ def map(opts, locale, invert: false)

attrs_opts = opts.slice(*i18n_keys)

predicate_builder = PredicateBuilder.new(attrs.backend_class)
predicate_builder = PredicateBuilder.new(attrs)
predicates += i18n_keys.map do |key|
predicate_builder.build(key, locale, opts.delete(key), attrs.options)
predicate_builder.build(key, locale, opts.delete(key), invert)
end

[attrs, attrs_opts]
}.compact

# TODO: inline this
inverter = ::ActiveRecord::Relation::WhereClause.new([]).method(:invert_predicate) if invert
predicates = predicates.map(&inverter.method(:call)) if invert

[opts, predicates.inject(&:and), map]
end
end

class PredicateBuilder
def initialize(backend_class)
@backend_class = backend_class
attr_reader :backend_class, :backend_options

def initialize(attributes)
@backend_class = attributes.backend_class
@backend_options = attributes.options
end

def build(attr, locale, values, invert)
predicate = _build(attr, locale, values)
predicate = invert(predicate) if invert
predicate
end

def build(attr, locale, values, backend_options)
node = @backend_class.build_node(attr, locale, backend_options)
private

def _build(attr, locale, values)
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) }
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?
Expand All @@ -112,6 +119,11 @@ def build(attr, locale, values, backend_options)
def collapse(value)
value.is_a?(Array) ? value.uniq : value
end

# TODO: inline this
def invert(predicate)
::ActiveRecord::Relation::WhereClause.new([]).method(:invert_predicate)[predicate]
end
end

private_constant :WhereChain, :ClauseMapper, :PredicateBuilder
Expand Down

0 comments on commit 5f106a2

Please sign in to comment.