您正在看到使用irb
进行调查的工件。
当你这样说:
> Product.first.title
#=> nil
你method_missing
将被称为懒加载的title
方法,你会得到nil
。
当你这样说:
> Product.first
你有效地这样做:
> p = Product.first; puts p.inspect
的第一款产品实例将被加载,然后irb
将调用inspect
它,AR将增加访问器方法。结果是产品现在有一个title
方法。因此,这样做:
> Product.first
> Product.first.title
不会叫你method_missing
都一样会有一个真正的title
方法Product.first.title
调用。
如果你再试一次这样的:
> Product.first; nil
> Product.first.title
你会看到两个nil
秒。
至于链接去,ActiveRecord的并没有真正检测结束,它只是一些方法调用自然需要从数据库中实际数据和一些不。
如果你打电话where
,order
,或任何其他的查询方法,你会得到一个ActiveRecord::Relation实例回来,你可以链中关系对象的详细查询方法和范围。例如,where
(其中的ActiveRecord ::关系由包括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
,任何Enumerable方法(即调用each
),...那么你在问具体实例,ActiveRecord将不得不执行查询来实现有问题的模型实例。例如,ActiveRecord::Relation#to_a
看起来是这样的:
def to_a
logging_query_plan do
exec_queries
end
end
和all
比来包裹to_a
多一点。
的ActiveRecord并不真正知道哪里链的末端,它只是不从数据库中加载任何东西,直到它有,所以你告诉它说链端出去,并取回了我一些数据。
我认为它确实检测到链条的末端:它是您无法取回查找代理对象的地方! – phoet 2012-03-01 19:58:36
这不是问题所在。问题在于''''''''''''''''''当''''''method_missing''在模型中被使用时'''Product.first''被调用直到''Product.first.title''返回'''nil'''。一旦你调用'''Product.first'''标题返回'''我的示例博客''''。 – user544941 2012-03-01 20:22:39
@ user544941:啊,我明白他在问什么:替换或绕过他的'method_missing'。 – 2012-03-01 20:41:36