class ActiveEnumerable::Finder

Public Class Methods

new(record) click to toggle source
# File lib/active_enumerable/finder.rb, line 4
def initialize(record)
  @method_caller = MethodCaller.new(record)
end

Public Instance Methods

is_of(conditions = {}) click to toggle source

Regex conditions

Finder.new({ name: "Timmy" }).is_of({ name: /Tim/ })
  #=> true

Hash conditions

record = { name: "Timmy", parents: [{ name: "Dad", age: 33 }, { name: "Mom", age: 29 }] } }

Matching array of partial hashes identities
  Finder.new(record).is_of(parents: [{ name: "Dad" }, { name: "Mom" }]))
    #=> true

Matching partial hashes identities to an array of hashes
  Finder.new(record).is_of(parents: { name: "Dad", age: 33 })
    #=> true

Array conditions

record = { name: "Timmy" }

Finder.new(record).is_of(name: %w(Timmy Fred))
  #=> true
Finder.new(record).is_of(name: ["Sammy", /Tim/])
  #=> true

Value conditions

record = { name: "Timmy", age: 10 }

Finder.new(record).is_of(name: "Timmy")
  #=> true
Finder.new(record).is_of(age: 10)
  #=> true

@param [Hash] conditions @return [true, false]

# File lib/active_enumerable/finder.rb, line 41
def is_of(conditions = {})
  conditions.all? do |col, match|
    case match
    when Proc
      proc_match(col, match)
    when Hash
      hash_match(col, match)
    when Array
      array_match(col, match)
    else
      compare(col, match)
    end
  end
end

Private Instance Methods

array_match(col, match) click to toggle source
# File lib/active_enumerable/finder.rb, line 77
def array_match(col, match)
  if @method_caller.call(col).is_a? Array
    if !(r = compare(col, match)) && match.map(&:class).uniq == [Hash]
      match.all? { |m| hash_match(col, m) }
    else
      r
    end
  else
    match.any? { |m| compare(col, m) }
  end
end
compare(col, match) click to toggle source
# File lib/active_enumerable/finder.rb, line 89
def compare(col, match)
  @method_caller.call(col).public_send(compare_by(match), match)
end
compare_by(match) click to toggle source
# File lib/active_enumerable/finder.rb, line 93
def compare_by(match)
  (match.is_a? Regexp) ? :=~ : :==
end
hash_match(col, match) click to toggle source
# File lib/active_enumerable/finder.rb, line 68
def hash_match(col, match)
  next_record = @method_caller.call(col)
  if next_record.is_a? Array
    next_record.any? { |record| Finder.new(record).is_of(match) }
  else
    Finder.new(next_record).is_of(match)
  end
end
proc_match(col, match) click to toggle source
# File lib/active_enumerable/finder.rb, line 58
def proc_match(col, match)
  return @method_caller.instance_exec(&match) unless col
  next_record = @method_caller.call(col)
  if next_record.is_a? Array
    next_record.all? { |record| Finder.new(record).is_of({nil => match}) }
  else
    MethodCaller.new(next_record).instance_exec(&match)
  end
end