Module: ApiResource::Finders::ClassMethods

Defined in:
lib/api_resource/finders.rb

Instance Method Summary collapse

Instance Method Details

#all(*args) ⇒ Object

This is an alias for find(:all). You can pass in all the same arguments to this method as you can to find(:all)



160
161
162
# File 'lib/api_resource/finders.rb', line 160

def all(*args)
  find(:all, *args)
end

#find(*arguments) ⇒ Object

Need to support the following cases => 1) Klass.find(1) => 2) Klass.find(:all, :params => => b) => 3) Klass.find(:first, :params => => b) => 4) Klass.includes(:assoc).find(1) => 5) Klass.active.find(1) => 6) Klass.includes(:assoc).find(:all, a => b)



28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
# File 'lib/api_resource/finders.rb', line 28

def find(*arguments)
  # make sure we have class data before loading
  self.load_resource_definition

  # Conditions sometimes call find, passing themselves as the last arg.
  if arguments.last.is_a?(ApiResource::Conditions::AbstractCondition)
    cond  = arguments.slice!(arguments.length - 1) 
  else
    cond  = nil
  end

  # Support options being passed in as a hash.
  options = arguments.extract_options! || {}

  # Remaining arguments are the scope.
  scope   = arguments

  # TODO: Make this into a class attribute properly (if it isn't already)
  # this is a little bit of a hack because options can sometimes be a Condition
  expiry = (options.is_a?(Hash) ? options.delete(:expires_in) : nil) || ApiResource::Base.ttl || 0
  ApiResource.with_ttl(expiry.to_f) do

    # If we have a condition or options to process...
    if cond || options.present?

      # Convert options hash to scope condition.
      if options.is_a?(Hash)
        opts = options.with_indifferent_access.delete(:params) || options || {}
        options = ApiResource::Conditions::ScopeCondition.new(opts, self)
      end

      # Combine all combinations of conditions and options
      if cond
        if options
          final_cond = cond.merge!(options)
        else
          final_cond = cond
        end
      elsif options
        final_cond = options
      end

      # If we have one argument, it's either a word argument
      # like first, last, or all, or its a number.
      if Array.wrap(scope).size == 1
        scope = scope.first if scope.is_a?(Array)

        # Create the finder with the conditions, then call the scope.
        # e.g. Class.scope(1).first
        if [:all, :first, :last].include?(scope)
          fnd = ApiResource::Finders::ResourceFinder.new(self, final_cond)
          fnd.send(scope)

        # If we have no conditions or they are only prefixes or
        # includes,and only one argument (not a word) then we 
        # only have a single item to find.
        # e.g. Class.includes.find(1)
        elsif final_cond.blank_conditions? || final_cond.conditions.include?(:foreign_key_id)
          scope = scope.first if scope.is_a?(Array)
          final_cond = final_cond.merge!(ApiResource::Conditions::ScopeCondition.new({:id => scope}, self))

          ApiResource::Finders::SingleFinder.new(self, final_cond).load
        else

          # Otherwise we are chaining a find onto
          # the end of a set of conditions.
          # e.g. Class.scope(1).find(1)
          fnd = final_cond.merge!(ApiResource::Conditions::ScopeCondition.new({:find => {:ids => scope}}, self))
          fnd.send(:all)
        end

      else

        # We are searching for multiple ids.
        # e.g. Class.scope(1).find(1,2)
        fnd = final_cond.merge!(ApiResource::Conditions::ScopeCondition.new({:find => {:ids => scope}}, self))
        fnd.send(:all)
      end

    else

      # No conditions
      if Array.wrap(scope).size == 1
        scope = scope.first if scope.is_a?(Array)

        # We are calling first, last, or all on the class itself.
        # e.g. Class.first
        if [:all, :first, :last].include?(scope)
          final_cond = ApiResource::Conditions::ScopeCondition.new({scope => true}, self)

          fnd = ApiResource::Finders::ResourceFinder.new(self, final_cond)
          fnd.send(scope)
        else

          # We are performing a simple find of a single object
          # e.g. Class.find(1)
          scope = scope.first if scope.is_a?(Array)
          final_cond = ApiResource::Conditions::ScopeCondition.new({:id => scope}, self)

          ApiResource::Finders::SingleFinder.new(self, final_cond).load
        end

      else
        # We are performing a find on multiple objects
        # e.g. Class.find(1,2)
        ApiResource::Conditions::ScopeCondition.new({:find => {:ids => scope}}, self)
        fnd.send(:all)

      end

    end

  end
end

#first(*args) ⇒ Object

A convenience wrapper for find(:first, *args). You can pass in all the same arguments to this method as you can to find(:first).



147
148
149
# File 'lib/api_resource/finders.rb', line 147

def first(*args)
  find(:first, *args)
end

#instantiate_collection(collection) ⇒ Object



164
165
166
167
168
# File 'lib/api_resource/finders.rb', line 164

def instantiate_collection(collection)
  collection.collect{|record| 
    instantiate_record(record)
  }
end

#instantiate_record(record) ⇒ Object



170
171
172
173
174
175
176
177
178
179
180
# File 'lib/api_resource/finders.rb', line 170

def instantiate_record(record)
  self.load_resource_definition
  ret = self.allocate
  ret.instance_variable_set(
    :@attributes, record.with_indifferent_access
  )
  ret.instance_variable_set(
    :@attributes_cache, HashWithIndifferentAccess.new
  )
  ret
end

#last(*args) ⇒ Object

A convenience wrapper for find(:last, *args). You can pass in all the same arguments to this method as you can to find(:last).



154
155
156
# File 'lib/api_resource/finders.rb', line 154

def last(*args)
  find(:last, *args)
end