Module: QueryableArray::DefaultFinder

Defined in:
lib/queryable_array/default_finder.rb

Overview

Allows objects to be searched by default_finders thru []. For example:

users = QueryableArray.new(User.all, :email)
users['[email protected]']    # => #<User @email='[email protected]'>
users['[email protected]']  # => nil

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#default_findersObject

Returns the value of attribute default_finders


14
15
16
# File 'lib/queryable_array/default_finder.rb', line 14

def default_finders
  @default_finders
end

Class Method Details

.included(base) ⇒ Object


10
11
12
# File 'lib/queryable_array/default_finder.rb', line 10

def self.included(base)
  base.send :include, Queryable
end

Instance Method Details

#[](key) ⇒ Object

If default_finders has been set and key is not a Fixnum, Range, or anything else natively supported by Array then it loops thru each default_finders and returns the first matching result of find_by(finder => key) or find_all(finder => key.first) if key is an Array. If key is already a Hash or an Array containing a Hash then it acts like an alias for find_by or find_all respectively. It also accepts a Proc or any object that responds to call. It behaves exactly like its superclass Array in all other cases.

pages = QueryableArray.new(Page.all, [:uri, :name])

pages['/']        # => #<Page @uri='/' @name='Home'>
pages['Home']     # => #<Page @uri='/' @name='Home'>
pages[/home/i]    # => #<Page @uri='/' @name='Home'>
pages['missing']  # => nil

pages[[/users/i]]    # => [#<Page @uri='/users/bob' @name='Bob'>, #<Page @uri='/users/steve' @name='Steve'>]
pages[[/missing/i]]  # => []

pages[proc { |page| page.uri == '/' }]         # => #<Page @uri='/' @name='Home'>
pages[[proc { |page| page.uri =~ /users/i }]]  # => [#<Page @uri='/users/bob' @name='Bob'>, #<Page @uri='/users/steve' @name='Steve'>]

45
46
47
48
49
50
51
52
53
54
# File 'lib/queryable_array/default_finder.rb', line 45

def [](key)
  super
rescue TypeError => error
  if default_finders.empty?
    raise error
  else
    method, key = key.is_a?(Array) ? [:find_all, key.first] : [:find_by, key]
    send method, &query(key)
  end
end

#initialize(array = [], default_finders = nil) ⇒ Object

Accepts an initial array which defaults to []. An optional default_finders may also be specified as the second argument which is used in QueryableArray#[] for quick lookups. It defaults to nil which disables this behavior. See the QueryableArray#[] method for more documentation.


20
21
22
23
# File 'lib/queryable_array/default_finder.rb', line 20

def initialize(array = [], default_finders = nil)
  super array
  self.default_finders = Array(default_finders)
end

#query(search) ⇒ Object

Converts a search into a Proc object that can be passed to find_by or find_all. If search is a Proc or an object that responds to call then it is wrapped in a Proc and returned. Otherwise the returned Proc loops thru each default_finders looking for a value that matches search.


60
61
62
63
64
65
66
67
68
69
70
# File 'lib/queryable_array/default_finder.rb', line 60

def query(search)
  Proc.new do |object|
    if search.respond_to?(:call)
      search.call object
    else
      default_finders.any? do |attribute|
        finder(attribute => search).call object
      end
    end
  end
end