Вы правы, второй путь пройдет через 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
и другими параметрами.