Enables dynamic finders like find_by_user_name(user_name) and
find_by_user_name_and_password(user_name, password) that are turned into
find(:first, :conditions => ["user_name = ?", user_name]) and
find(:first, :conditions => ["user_name = ? AND password = ?",
user_name, password]) respectively. Also works for find(:all), but using
find_all_by_amount(50) that are turned into find(:all, :conditions =>
["amount = ?", 50]).
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).
# File activerecord/lib/active_record/base.rb, line 1090
def method_missing(method_id, *arguments)
if match = /find_(all_by|by)_([_a-zA-Z]\w*)/.match(method_id.to_s)
finder, deprecated_finder = determine_finder(match), determine_deprecated_finder(match)
attribute_names = extract_attribute_names_from_match(match)
super unless all_attributes_exists?(attribute_names)
conditions = construct_conditions_from_arguments(attribute_names, arguments)
case extra_options = arguments[attribute_names.size]
when nil
options = { :conditions => conditions }
set_readonly_option!(options)
send(finder, options)
when Hash
finder_options = extra_options.merge(:conditions => conditions)
validate_find_options(finder_options)
set_readonly_option!(finder_options)
if extra_options[:conditions]
with_scope(:find => { :conditions => extra_options[:conditions] }) do
send(finder, finder_options)
end
else
send(finder, finder_options)
end
else
send(deprecated_finder, conditions, *arguments[attribute_names.length..-1]) # deprecated API
end
elsif match = /find_or_create_by_([_a-zA-Z]\w*)/.match(method_id.to_s)
attribute_names = extract_attribute_names_from_match(match)
super unless all_attributes_exists?(attribute_names)
options = { :conditions => construct_conditions_from_arguments(attribute_names, arguments) }
set_readonly_option!(options)
find_initial(options) || create(construct_attributes_from_arguments(attribute_names, arguments))
else
super
end
end