has_one动态生成的访问器

时间:2013-10-22 10:32:52

标签: ruby-on-rails ruby activerecord model has-one

当在模型上声明has_many关系时,会动态添加一个访问器方法,允许传入一组id:

class Example < ActiveRecord::Base
   has_many :foos
end

允许:

$ m = Example.create!
$ m.foo_ids = [1, 2, 3]

但是,当声明has_one关系时,会创建这样的访问者:

class Example < ActiveRecord::Base
   has_one :foo
end

不允许:

$ m = Example.create!
$ m.foo_id = 1 # No method error

为什么会出现这种差异?

为什么可以使用它们的ID设置表单中的多个关联,但是为了设置单一关联,需要嵌套表单并且需要在模型上定义accepts_nested_attributes_for?这感觉就像API中的差异一样。

5 个答案:

答案 0 :(得分:1)

对于has_one,您应该使用单个而不是复数:

has_one :foo

答案 1 :(得分:1)

这是因为几乎没有关联宏创建"{{association_name}}_id"访问者 - 它是由ActiveRecord根据DB表中的列创建的。此外,has_one关联意味着关联模型具有外键列,因此如果您的关联与DB模式一致,则不应引发错误:

foo = Foo.new
foo.example_id

答案 2 :(得分:1)

根据guidecollection_singular_ids=(m.foo_ids =)方法使集合仅包含由提供的主键值标识的对象,通过适当添加和删除。这意味着它会将具有id [1,2,3]的foos分配给示例m。

现在他们有一个不同的方法collection=objects(m.foo =),它将接收foo对象数组作为参数,并将这些foos与示例相关联。

最后,当我们使用has_one关联时,只有一个对象与该示例相关联。所以我们不需要两种不同的方法来进行相同的工作,因此它们没有collection_singular_id=方法,因为它会让人感到困惑,但它们有association=(associate)方法来分配关联。

从指南中:

  

association =方法为此对象分配关联对象。在幕后,这意味着从该对象中提取主键并将关联对象的外键设置为相同的值。

答案 3 :(得分:0)

为什么要为单个实例创建该访问者?无需向其传递ID数组。访问者foo_id=等同于foo.id=,为什么要创建它?

答案 4 :(得分:-2)

对于动态生成的访问器,您应该在模型中使用method_missing。

使动态关联模型使用多态关联。