Can anyone tell me what is the difference between build and new command on Rails?
I observed a difference between .build and .new when using them to create a 'dummy' object for a view form, using a using nested resource.
.build creates a parent_id .new does not
Nested Resource example: @list.items (where Item is nested under List)
@list.items.build ...produces an object with all nil values EXCEPT for list_id.
Item.new creates a new item object, with all nil values.
It showed up in my 'show' page when iterating over @list.items Not an issue until I needed @list.items further down same 'show' page in another form, where iteration on @list.items exposed the item (the one produced by .build) that had an associated list_id, but nothing else.
@list.items.build => #
2.2.3 :002 > Item.all.build => #
2.2.3 :003 > Item.new => # 2.2.3 :004 >
There was a time when build populated the caller with the new instance but new didn't. Right now from Rails 4 both new and build populate the caller with the new instance. Just play around in the console if you want to get an idea.
new is for a new instance of a specific model:
foo = Foo.new
build is for creating a new instance within an AR association:
bar = foo.build_bar # (has_one or belongs_to)
or
bar = foo.bars.build # (has\_many, habtm or has_many :through)
http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html
Update
Per @toklands's suggestion, build and new are aliases as defined in ActiveRecord::Relation:
So if class Foo has_many Bars, the following have identical effects:
foo.bars.new
<=> foo.bars.build
Bar.where(:foo_id=>foo.id).new
<=> Bar.where(:foo_id=>foo.id).build
And if !foo.new_record?
foo.bars.new
<=> Bar.where(:foo_id=>foo.id).new
New and build are same as per the documentation https://github.com/rails/rails/blob/master/activerecord/lib/active_record/relation.rb
Prior to rails 2.2, you needed build for the has_many/has_and_belongs_to_many part of the relation in order for the new record to automatically have it's foreign keys set. For example:
user.timesheets.build
would set the foreign key. I think for rails 2.2 and onwards, new and build do the same thing for has_many and has_and_belongs_to_many relations.