module ActiveRecord::FilterableBy

Public Class Methods

merge(scope, unscoped, hash, name, **opts, &block) click to toggle source
# File lib/filterable_by.rb, line 17
def merge(scope, unscoped, hash, name, **opts, &block)
  key = name
  positive = normalize(hash[key]) if hash.key?(key)
  if positive.present?
    sub = eval_scope(scope, unscoped, positive, **opts, &block)
    return nil unless sub

    scope = scope.merge(sub)
  end

  key = "#{name}_not"
  negative = normalize(hash[key]) if hash.key?(key)
  if negative.present?
    sub = eval_scope(scope, unscoped, negative, **opts, &block)
    return nil unless sub

    scope = scope.merge(invert_where(sub))
  end

  scope
end
normalize(value) click to toggle source
# File lib/filterable_by.rb, line 8
def normalize(value)
  case value
  when String, Numeric
    value
  when Array
    value.select {|v| normalize(v) }
  end
end

Private Class Methods

eval_scope(scope, unscoped, value, **opts, &block) click to toggle source
# File lib/filterable_by.rb, line 41
def eval_scope(scope, unscoped, value, **opts, &block)
  if block.arity == 2
    scope.instance_exec(unscoped, value, **opts, &block)
  else
    scope.instance_exec(value, **opts, &block)
  end
end
invert_where(scope) click to toggle source
# File lib/filterable_by.rb, line 49
def invert_where(scope)
  if scope.respond_to?(:invert_where!)
    scope.invert_where!
  else
    scope.where_clause = scope.where_clause.invert
  end
  scope
end