Вы видите артефакт использования irb
для расследования вещей.
Когда вы говорите это:
> Product.first.title
#=> nil
Ваш method_missing
будет вызван для ленивой загрузкиtitle
метод, и вы получите nil
.
Когда вы говорите это:
> Product.first
Вы эффективно делаете это:
> p = Product.first; puts p.inspect
Первый продуктэкземпляр будет загружен, а затем irb
вызовет на нем inspect
, и AR добавит методы доступа по пути.В результате у Product теперь будет метод title
.Следовательно, делая это:
> Product.first
> Product.first.title
вообще не будет вызывать ваш method_missing
, так как будет существовать настоящий title
метод для вызова Product.first.title
.
Если вы попытаетесьснова вот так:
> Product.first; nil
> Product.first.title
Вы увидите два nil
s.
Что касается цепочки, ActiveRecord на самом деле не определяет конец, это просточто некоторые вызовы методов, естественно, требуют реальных данных из базы данных, а некоторые - нет.
Если вы вызываете where
, order
или любой другой метод запроса, вы получаете ActiveRecord:: Relation экземпляр обратно, и вы можете связать больше методов и областей запросов для этого объекта отношения.Например, where
(который ActiveRecord :: Relation получает путем включения ActiveRecord :: QueryMethods ) выглядит следующим образом:
def where(opts, *rest)
return self if opts.blank?
relation = clone
relation.where_values += build_where(opts, rest)
relation
end
, поэтому он просто создаеткопия текущего запроса, добавляет к копии несколько вещей и возвращает ее обратно.
Если вы звоните first
, last
, to_a
, all
, любой из Перечислимые методы (то есть вы вызываете each
), ... тогда вы спрашиваете о конкретных экземплярах, и ActiveRecord должен будет выполнить запрос, чтобы реализовать рассматриваемые экземпляры модели.Например, ActiveRecord::Relation#to_a
выглядит так:
def to_a
logging_query_plan do
exec_queries
end
end
и all
немного больше, чем обертка вокруг to_a
.
ActiveRecord на самом деле не знает, где находится конец цепочки, он просто ничего не загружает из базы данных до тех пор, пока он не должен, чтобы вы сказали ему, где заканчивается цепочка, сказав, иди и принесите мне некоторые данные..