2010-03-12 37 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如何重映射成员? ?