Module: ActiveRecord::DynamicMatchers
- Included in:
- Base
- Defined in:
- lib/active_record/dynamic_matchers.rb
Instance Method Summary collapse
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(method_id, *arguments, &block) ⇒ Object (private)
Enables dynamic finders like User.find_by_user_name(user_name)
and <tt>User.scoped_by_user_name(user_name). Refer to Dynamic attribute-based finders section at the top of this file for more detailed information.
It’s even possible to use all the additional parameters to find
. For example, the full interface for find_all_by_amount
is actually find_all_by_amount(amount, options)
.
Each dynamic finder using scoped_by_*
is also defined in the class after it is first invoked, so that future attempts to use it do not run through method_missing.
24 25 26 27 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 |
# File 'lib/active_record/dynamic_matchers.rb', line 24 def method_missing(method_id, *arguments, &block) if match = (DynamicFinderMatch.match(method_id) || DynamicScopeMatch.match(method_id)) attribute_names = match.attribute_names super unless all_attributes_exists?(attribute_names) if !(match.is_a?(DynamicFinderMatch) && match.instantiator? && arguments.first.is_a?(Hash)) && arguments.size < attribute_names.size method_trace = "#{__FILE__}:#{__LINE__}:in `#{method_id}'" backtrace = [method_trace] + caller raise ArgumentError, "wrong number of arguments (#{arguments.size} for #{attribute_names.size})", backtrace end if match.respond_to?(:scope?) && match.scope? self.class_eval <<-METHOD, __FILE__, __LINE__ + 1 def self.#{method_id}(*args) # def self.scoped_by_user_name_and_password(*args) attributes = Hash[[:#{attribute_names.join(',:')}].zip(args)] # attributes = Hash[[:user_name, :password].zip(args)] # scoped(:conditions => attributes) # scoped(:conditions => attributes) end # end METHOD send(method_id, *arguments) elsif match.finder? = arguments. relation = .any? ? scoped() : scoped relation.send :find_by_attributes, match, attribute_names, *arguments, &block elsif match.instantiator? scoped.send :find_or_instantiator_by_attributes, match, attribute_names, *arguments, &block end else super end end |
Instance Method Details
#respond_to?(method_id, include_private = false) ⇒ Boolean
3 4 5 6 7 8 9 10 11 |
# File 'lib/active_record/dynamic_matchers.rb', line 3 def respond_to?(method_id, include_private = false) if match = DynamicFinderMatch.match(method_id) return true if all_attributes_exists?(match.attribute_names) elsif match = DynamicScopeMatch.match(method_id) return true if all_attributes_exists?(match.attribute_names) end super end |