您正在看到使用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