当在模型上声明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中的差异一样。
答案 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)
根据guide,collection_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。
使动态关联模型使用多态关联。