有时候这种方法有效,有时则不然:
class Foo
has_many :bars
end
class Bar
belongs_to :foo
end
foo = Foo.create
bar1 = Bar.create
bar2 = Bar.create
foo.bars << [bar1, bar2]
修复方法是单独分配它们:
foo.bars << bar1
foo.bars << bar2
更新:
在我正在试验的案例中,foo
和bar
不是新对象。
我什么时候没有看到模式。更重要的是,看起来rails如何处理质量分配(attr_accessible
)这里很奇怪。如果我有代码来提出异常,如果尝试进行质量分配(以帮助我在开发过程中捕获错误),它就不起作用。但是,如果我没有提出这些例外情况,那么它确实有效,即使foo_id
列表中的attr_accessible
列表都没有。
答案 0 :(得分:2)
通常,如果你执行“&lt;&lt; [x,y]”,你不会将x和y推送到数组,而是将包含x和y的新数组(使其成为多维数组):
> test = Array.new
=> []
> test << [1, 2]
=> [[1, 2]]
您可能希望改为使用“&lt;&lt; x&lt;&lt; y”:
> test = Array.new
=> []
> test << 1 << 2
=> [1, 2]
答案 1 :(得分:1)
对于新创建的对象,我建议使用has_many
关联辅助方法build
或create
:
foo = Foo.create
bar1 = foo.bars.create # saves the record
bar2 = foo.bars.build # does not save the record
bar2.save! # actually creates the object
这些助手可以采用属性哈希,就像常规create
和new
一样 - 唯一的区别是他们会自动为您设置关联。
如果您尝试添加到foo
的Bar对象已存在,我的偏好是在bar对象中设置关联:
foo = Foo.create # alternately Foo.find(1)
bar = Bar.find(1) # alternately Bar.new, but then use Foo.bars.build
bar.foo = foo
bar.save!
这样,追踪问题就容易得多,例如:您可以轻松处理验证错误。与<<
的唯一区别在于它保持foo.bars
最新而不重新加载 - 所以如果您需要foo.bars
立即更新完整的条形列表(旧条形图和新关联的栏),您可能想要使用<<
。
作为最后一个脚注,您还可以使用build
助手一次创建整个内容:
foo = Foo.new
bar1 = Foo.bars.build
bar2 = Foo.bars.build
foo.save! # saves foo, bar1, and bar2 in one transaction,
# provided they are all valid
答案 2 :(得分:0)
语法foo.bars << [bar1,bar2]
没有任何问题。关于has_many关联中定义的<<
方法,Rails API说:
集合&lt;&lt;(object,...)
添加一个或多个对象 通过设置他们的外国收集 集合主键的键。 请注意,此操作立即生效 在没有等待的情况下触发更新sql 父节点上的保存或更新呼叫 对象
这可能会给你一些关于(显然)不一致行为的线索。