class method
self.method_missing
Ruby on Rails 3.1.12
Since v2.2.3 Last seen in v3.1.12 PrivateSignature
self.method_missing(method_id, *arguments, &block)
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.
Parameters
-
method_idreq -
argumentsrest -
blockblock
Source
# File activerecord/lib/active_record/base.rb, line 1058
def method_missing(method_id, *arguments, &block)
if match = DynamicFinderMatch.match(method_id)
attribute_names = match.attribute_names
super unless all_attributes_exists?(attribute_names)
if !arguments.first.is_a?(Hash) && arguments.size < attribute_names.size
ActiveSupport::Deprecation.warn(<<-eowarn)
Calling dynamic finder with less number of arguments than the number of attributes in the method name is deprecated and will raise an ArgumentError in the next version of Rails. Please pass `nil' explicitly to the arguments that are left out.
eowarn
end
if match.finder?
options = if arguments.length > attribute_names.size
arguments.extract_options!
else
{}
end
relation = options.any? ? scoped(options) : scoped
relation.send :find_by_attributes, match, attribute_names, *arguments
elsif match.instantiator?
scoped.send :find_or_instantiator_by_attributes, match, attribute_names, *arguments, &block
end
elsif match = DynamicScopeMatch.match(method_id)
attribute_names = match.attribute_names
super unless all_attributes_exists?(attribute_names)
if arguments.size < attribute_names.size
ActiveSupport::Deprecation.warn(
"Calling dynamic scope with less number of arguments than the number of attributes in " \
"the method name is deprecated and will raise an ArgumentError in the next version of Rails. " \
"Please pass `nil' explicitly to the arguments that are left out."
)
end
if 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)
end
else
super
end
end
Defined in activerecord/lib/active_record/base.rb line 1058
· View on GitHub
· Improve this page
· Find usages on GitHub
Defined in ActiveRecord::Base