Create! should return an Active Record object no matter what

I just using the bang versions of save and create after seeing Rick
(technoweenie) use it in his code. I like it much better.

I have a problem with the create! method. It doesn’t return an Active
Record object if it fails. That means you can’t display the errors on
the object. Whats the point than?

Here is a broken example that should work.

def create
@product = Product.create! params[:product]
redirect_to :action => “show”, :id => @product.id
rescue ActiveRecord::RecordInvalid
render :action => ‘new’
end

If it fails @products is nil. You can’t show any errors.

Here is my work around.

def create
@product = Product.create params[:product]
@product.save!
redirect_to :action => “show”, :id => @product.id
rescue ActiveRecord::RecordInvalid
render :action => ‘new’
end

The normal create is nice enough to keep @product around to display the
errors.

This is how it is documented and supposed to be.

I’m going to try to “monkey patch” to make create! return an Active
Record object.

I agree with you.

I can’t see the purpose of a create! at all. You didn’t have an instance
in the first place, so how can it be updating it?

I’m going work on a patch.

Please don’t submit one. I want to be a “Rails Contributor”. :slight_smile:

On Wed, Jul 26, 2006, Josh P. wrote:

I have a problem with the create! method. It doesn’t return an Active
Record object if it fails. That means you can’t display the errors on
the object. Whats the point than?

As you discovered lower down, it should be raising an exception. This
is normal for Ruby, where methods shouldn’t return anything, as they’re
meant to do thing in-place.

I agree with you and Dr. Nic, it doesn’t make any sense to me to have
save!
and create! methods, but I guess some people have found utility in them.

Ben

Um… Maybe it just needs a documentation patch to clear things up.

Found in changelog

Add Model.create! to match existing model.save! method. When save!
raises RecordInvalid, you can catch the exception, retrieve the invalid
record (invalid_exception.record), and see its errors
(invalid_exception.record.errors).