2010-03-12 25 views
2

鑑於從ActiveRecord命名爲Foo s的集合,爲什麼Array#include?似乎沒有調用Foo.==index呢?Array :: include?在ActiveRecord集合不調用op ==?

class Foo < ActiveRecord::Base 
    def ==(s) 
    self.name == s 
    end 
end 

class Bar < ActiveRecord::Base 
    has_many :foos 
end 

bar.foos << Foo.new(:name => 'hmm') 

bar.foos.all.include?('hmm') # does select all from db every time 
=> true 

bar.foos.include?('hmm') # does not go to db, but does not find the Foo! 
=> false 

bar.foos.index('hmm') # does not go to db, but does find the Foo[0] ! 
=> 0 

bar.foos.index('eh') # no such object 
=> nil 

我理解淺薄有關代理,但(沒有繞道進入AR源)爲什麼指數表現看似正確,但包括哪些內容?不是 !?

這是代理行爲中的錯誤,還是/此行爲記錄在某處?

謝謝。

+0

會員?作品。爲什麼不包括? – tribalvibes 2010-03-12 06:38:04

回答

0

這是因爲bar.foos不返回ActiveRecord::Base對象,但返回AssociationProxy(請參閱association_proxy.rb)。

我不建議您在關聯代理中重新定義==,或者您將改變應用程序中所有關聯的行爲。

0

西蒙,這不是我要找的答案(但我喜歡你認爲;-)

,提示我雖然讀的文件中,association_proxy.rb(實際上呃源代碼,AssociationCollection其模擬的方式陣列由協會返回的收集方法。)

AssociationCollection.include?

File activerecord/lib/active_record/associations/association_collection.rb, line 332 
     def include?(record) 
     return false unless record.is_a?(@reflection.klass) 
     load_target if @reflection.options[:finder_sql] && !loaded? 
     return @target.include?(record) if loaded? 
     exists?(record) 
     end 

尋找貌似ARG record預計@reflection.klass類型而Array.include?需要一個對象,並使用在數組對象上定義的比較器==

好吧,這不是我想要的AR。由於Enumerable.member?似乎在關聯集合上工作,我會用它。我想掃描緩存的集合,而不是再次訪問數據庫。也許有人可以解釋AssociationCollection如何重映射成員? ?

相關問題