在Rails中,build和new有什么区别?

40

有没有人能告诉我Rails中build和new命令的区别是什么?

5个回答

73

new用于创建特定模型的新实例:

foo = Foo.new

build用于在AR关联中创建一个新实例:

bar = foo.build_bar  # (has_one or belongs_to)
或者
bar = foo.bars.build # (has\_many, habtm or has_many :through)

http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html

更新

根据 @toklands 的建议,在 ActiveRecord::Relation 中,build 和 new 是别名:

所以如果 Foo 类有多个 Bars,以下操作具有相同的效果:

  • foo.bars.new <=> foo.bars.build
  • Bar.where(:foo_id=>foo.id).new <=> Bar.where(:foo_id=>foo.id).build

如果 !foo.new_record?

  • foo.bars.new <=> Bar.where(:foo_id=>foo.id).new

15
确实,但有一件事情缺失了:foo.bars.build和foo.bars.new的区别(或等价性)。 - tokland
1
似乎在Rails >3.2.6中没有区别。https://dev59.com/gm445IYBdhLWcg3wQoEj - Andreas
5
你能否将你的旧答案和新的更新答案分开,并注明版本号?目前看起来你说了一件事情,然后又自相矛盾,没有明确指出哪一个是被覆盖或过时的。 - ahnbizcad

23

3

在 Rails 2.2 之前,你需要构建 has_many/has_and_belongs_to_many 关系的部分,以便新记录自动设置其外键。例如:

user.timesheets.build

将设置外键。我认为对于Rails 2.2及其以后版本,对于has_many和has_and_belongs_to_many关系,new和build的作用是相同的。


2
曾经有个时期,使用 build 方法创建实例时,实例不会被传递给调用者;而使用 new 方法创建实例时,则会传递给调用者。但是从 Rails 4 开始,无论是使用 new 还是 build 方法创建实例,都会将实例传递给调用者。如果你想了解更多,可以在控制台中进行测试。

1

我注意到在使用嵌套资源创建“虚拟”视图表单对象时,.build和.new之间存在差异。

.build会创建一个parent_id,而.new则不会。

嵌套资源示例: @list.items(其中Item嵌套在List下)

@list.items.build ...会生成一个除了list_id之外所有值都为nil的对象。

Item.new会创建一个新的item对象,其中所有值都为nil。

当我在迭代@list.items时,在我的“show”页面中出现了它。这并不是问题,直到我需要在同一“show”页面中的另一个表单中进一步使用@list.items,其中对@list.items的迭代会暴露由.build生成的具有关联list_id但没有其他内容的项。

以下是一些示例输出...

@list.items.build => #


2.2.3 :002 > Item.all.build => #

2.2.3 :002 > Item.all.build => #


2.2.3 :003 > Item.new => # 2.2.3 :004 >

2.2.3 :003 > 创建新项目 => # 2.2.3 :004 >


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接