What is the difference between build and new


#1

I use new in almost all my controllers, but sometimes I have seen the
build method inside the controllers of some apps. Can someone explain
when should I use build?


#2

John S. wrote:

I use new in almost all my controllers, but sometimes I have seen the
build method inside the controllers of some apps. Can someone explain
when should I use build?

.build fixes the fact you cannot say this:

my_post.tags.new(:name => ‘reggae’)

The new() operator is special, and your editor might color it different.
So the
architects of ActiveRecord use .build() instead.

Both create a new object. But shouldn’t we just use this?

my_post.tags.create(:name => ‘reggae’)
my_post.tags.create!(:name => ‘reggae’)

What do they do?


Phlip


#3

On Feb 14, 2009, at 2:37 PM, Phlip wrote:

The new() operator is special, and your editor might color it

Phlip

In particular, #build (and #create) automatically set, in this case,
the :post_id of the associated Tag object to be my_post.id

There are times when you want to work briefly with an unsaved object
and #build is more appropriate than #create

-Rob

Rob B. http://agileconsultingllc.com
removed_email_address@domain.invalid


#4

On Feb 15, 1:26 am, Rob B. removed_email_address@domain.invalid
wrote:

In particular, #build (and #create) automatically set, in this case,
the :post_id of the associated Tag object to be my_post.id

There are times when you want to work briefly with an unsaved object
and #build is more appropriate than #create

can #build support multiple nested models? like i have a ‘Deal’ with
many ‘Orders’ and an ‘Order’ with many ‘Duties’.
all three need to created inside the Deal Controller.

Regards


#5

build does not save the object. create does. if saving fails, create
returns false, create! raises error (useful in migration, will
rollback)


#6

On Feb 15, 2009, at 7:13 AM, Sahil D. wrote:

all three need to created inside the Deal Controller.

Regards

You have to have a saved model object in order to use #build or it
can’t assign the post_id to the new Tag (or in your case, the deal_id
on the order or the order_id to the duty). If you need to save them
all at the “same time” you’ll have to use a transaction and link them
up yourself. (Warning: this pseudo-code is just off the top of my
head; you’ll need tests!)

@deal = Deal.new(…)
@order = Order.new(…)
@duty = Duty.new(…)

if everything_is_valid?
Duty.transaction do
Order.transaction do
Deal.transaction do
if @deal.save
@deal.orders << @order
if @order.save
@order.duties << @duty
if @duty.save
# Great!
else
# recover from unsavable duty (or use save!)
end
else
# recover from unsavable order (or use save!)
end
else
# recover from unsavable deal (or use save!)
end
end
end
end
else

complain about the invalid parts

end

-Rob

Rob B. http://agileconsultingllc.com
removed_email_address@domain.invalid


#7

On 15 Feb 2009, at 20:27, Rob B. wrote:

can #build support multiple nested models? like i have a ‘Deal’ with
up yourself. (Warning: this pseudo-code is just off the top of my
head; you’ll need tests!)

Actually build does handle being called on unsaved objects (it didn’t
used to on has many through but that was the exception):

new_user = User.new
=> #<User id: nil, name: nil, state: nil, created_at: nil, updated_at:
nil>

post = new_user.posts.build
=> #<Post id: nil, user_id: nil, active: nil, created_at: nil,
updated_at: nil>

comment = post.comments.build
=> #<Comment id: nil, post_id: nil, created_at: nil, updated_at: nil>

new_user.save
=> true

new_user
=> #<User id: 4, name: nil, state: nil, created_at: “2009-02-16
16:17:35”, updated_at: “2009-02-16 16:17:35”>

post
=> #<Post id: 4, user_id: 4, active: nil, created_at: “2009-02-16
16:17:35”, updated_at: “2009-02-16 16:17:35”>

comment
=> #<Comment id: 1, post_id: 4, created_at: “2009-02-16 16:17:35”,
updated_at: “2009-02-16 16:17:35”>

Fred


#8

On Feb 16, 1:27 am, Rob B. removed_email_address@domain.invalid
wrote:

You have to have a saved model object in order to use #build or it
can’t assign the post_id to the new Tag (or in your case, the deal_id
on the order or the order_id to the duty). If you need to save them
all at the “same time” you’ll have to use a transaction and link them
up yourself.

i am using complex forms given in “Advanced Rails Recipes”. its doing
a good job in saving a deal with an order. but 2nd level of nesting
with duties is not working. Is there a plugin out there that can
handle multiple levels of model nesting?

     if @deal.save
       end
     else
       # recover from unsavable deal (or use save!)
     end
   end
 end

end
else

complain about the invalid parts

end

i think for the above code, i need to create virtual attributes inside
the ‘deal’ and ‘order’ models. Can this be handled using a form_for
@deal and using partials inside it or do i need to use the form_tag
and create separate params for deal, order, duty?

Regards

Sahil