Rails ActiveRecord has_one与Object方法覆盖一起关联

时间:2011-11-17 07:57:35

标签: ruby-on-rails-3 activerecord

我遇到了has_one关联与Object方法覆盖相结合的特殊问题。有人可以向我解释发生了什么吗?

这是怎么回事:

我在has_oneSupplier之间存在Account关系,就像在Rails指南中使用的has_one示例的示例一样。

供应商:

class Supplier < ActiveRecord::Base

  validates :name, :presence => true

  has_one :account

  nilify_blanks
end

帐户:

class Account < ActiveRecord::Base

  belongs_to :supplier

  validates :supplier_id, :presence => true

  nilify_blanks

  def foo
    puts 'in account'
  end

  def to_s
    puts 'in account'
  end

end

我在foo上的方法Object如下:

class Object
  def foo
    puts 'in object'
  end
end

我打电话的时候:

Supplier#account#to_s 

我得到'帐户'

我打电话的时候:

Supplier#account#foo

我得到'对象'

虽然我希望它可以打印'帐户'

有没有人知道为什么会这样?这是Rails ActiveRecord中的错误吗?

提前致谢

P.S。如果需要,您可以从这里获得一个完整的应用程序来演示问题:

https://github.com/pmatsinopoulos/test_association_and_object_method_override.git

1 个答案:

答案 0 :(得分:2)

在和我的一个朋友做了一些投资后,得到了协商的方式。

当我们执行Supplier.account时,它会为您提供AssociationProxy的对象而不是帐户对象。 如果关联对象的定义本身不存在,则AssociationProxy会将所有方法委托给关联对象(它还会委托类,检查等方法,以便获取实际的类名)。 现在,当我们在Object类中添加foo时,它在AssociationProxy中可用,当你说Supplier.account时,它会从AssociationProxy调用foo,而不是从帐户调用。

如果要从帐户使用目标方法调用foo来获取实际帐户对象,如

Supplier.account.target.foo #=> foo from account