views:

31

answers:

1
Student.find(:all, :conditions => [‘name = ? and status = ?’ ‘mohit’, 1])

Vs

Student.find_all_by_name_and_status(‘mohit’, 1)

Both the queries will result the same set of row but first one is preferable cause in the second way there will be exception generated method_missing and then rails will try to relate it as dynamic method. if fine then result set to returned. Can any body explain me this in a good manner. What exactly is happening behind the screen. Please correct me if i am wrong.

+2  A: 

You are right, the second way will go through a method_missing. ActiveRecord will parse the method name and if it is a valid name, it will generate a method on the fly.

If you look in the source of ActiveRecord::Base, in method_missing you'll see that developers left us a comment of how this generated method would look like:

# def self.find_by_login_and_activated(*args)
#   options = args.extract_options!
#   attributes = construct_attributes_from_arguments(
#     [:login,:activated],
#     args
#   )
#   finder_options = { :conditions => attributes }
#   validate_find_options(options)
#   set_readonly_option!(options)
#
#   if options[:conditions]
#     with_scope(:find => finder_options) do
#       find(:first, options)
#     end
#   else
#     find(:first, options.merge(finder_options))
#   end
# end

So you see that generally it boils down to the same find method.

I would not say that the first way is preferable because of method_missing, because the performance penalty for that is negligible. The second way reads better and works well if you just need to fetch records based on attributes equal to some values.

However, this second form does not allow you to do anything beyond equality comparison (e.g., range comparison, "not equal to" expressions, joins, etc.). In such cases, you'll just have to use the find method with appropriate conditions and other parameters.

neutrino