Вы правы, второй способ пройдет через method_missing
. ActiveRecord будет анализировать имя метода и, если он является допустимым именем, он будет генерировать метод «на лету».
Если посмотреть в источнике ActiveRecord::Base
, в method_missing
вы увидите, что разработчики оставили нам комментарий о том, как этот сгенерированный метод будет выглядеть следующим образом:
# 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
Итак, вы видите, что в целом она сводится к тот же find
способ.
Я бы не сказал, что первый способ предпочтительнее из-за method_missing
, потому что штраф за исполнение для этого ничтожно мал. Второй способ читается лучше и работает хорошо, если вам просто нужно извлекать записи на основе атрибутов, равных некоторым значениям.
Однако эта вторая форма не позволяет делать что-либо помимо сравнения сравнений (например, сравнение диапазона, «не равно» выражениям, объединениям и т. Д.). В таких случаях вам просто нужно использовать метод find
с соответствующими conditions
и другими параметрами.