Module: QueryableArray::Queryable
- Included in:
- QueryableArray
- Defined in:
- lib/queryable_array/queryable.rb
Overview
Allows find_by
and find_all
to accept search hashes which are converted into Proc
searches and passed as the block arguments for find
and find_all
respectively
Instance Method Summary collapse
-
#find_all(search = {}, &block) ⇒ Object
Returns a dup’d
Queryable
replaced with objects matching thesearch
criteria. -
#find_by(search = {}, &block) ⇒ Object
Behaves exactly like
find_all
but only returns the first match. -
#finder(search) ⇒ Object
Accepts a
search
hash and returns aProc
which determines if all of an object’s searched attributes match their expected values.
Instance Method Details
#find_all(search = {}, &block) ⇒ Object
Returns a dup’d Queryable
replaced with objects matching the search
criteria. When a block
is specified, it behaves exactly like Enumerable#find_all. Otherwise the search
hash is converted into a finder
proc and passed as the block argument to Enumerable#find_all.
users.find_all(age: 30) # => [#<User @age=30>, #<User @age=30>, ...]
users.find_all(name: 'missing') # => []
users.find_all { |user| user.age < 30 } # => [#<User @age=22>, #<User @age=26>, ...]
14 15 16 17 |
# File 'lib/queryable_array/queryable.rb', line 14 def find_all(search = {}, &block) block = finder search unless block_given? dup.replace super(&block) end |
#find_by(search = {}, &block) ⇒ Object
Behaves exactly like find_all
but only returns the first match. If no match is found then nil
is returned.
users.find_by(age: 25) # => #<User @age=25>
users.find_by(name: 'missing') # => nil
24 25 26 27 |
# File 'lib/queryable_array/queryable.rb', line 24 def find_by(search = {}, &block) block = finder search unless block_given? find(&block) end |
#finder(search) ⇒ Object
Accepts a search
hash and returns a Proc
which determines if all of an object’s searched attributes match their expected values. It can be used as the block arguments for find
, find_by
and find_all
.
Values are compared with expected values using ==
or ===
. If the expected value is a Proc
or anything that responds to call
then it is evaluated with the value
as an argument and checks for a response other than nil
or false
.
Searched attributes first check if the object
responds to the attribute so NoMethodError
is never thrown if an attribute doesn’t exist.
query = finder(name: 'bob') # => proc { |user| user.name == 'bob' } # pseudo code
query User.new(name: 'steve') # => false
query User.new(name: 'bob') # => true
users.find(&query) # => #<User @name='bob'>
users.find &finder(missing: 'value') # => nil
48 49 50 51 52 53 54 55 |
# File 'lib/queryable_array/queryable.rb', line 48 def finder(search) Proc.new do |object| search.all? do |attribute, expected| value = object.send attribute if object.respond_to?(attribute) expected == value || expected === value || (expected.respond_to?(:call) && expected.call(value)) end end end |