5

Sorry if the question is obvious, I am only starting to work with Rails.
I have a following code in several controller methods now:

respond_to do |format| if @project.save format.html { redirect_to(edit_project_url(@project), :notice => '#{user.name} added to #{role}.') } format.js else format.html { render :action => "edit" } format.js #... end end 

So the question is, what is the best way to do the same thing for errors in all methods?
Is it recommended that I use save! and handle it in rescue_action?

Or should I do my own respond method and pass save in a block?

2 Answers 2

16

It's often more convenient to use the exception-raising variant of save and rescue that later in the block than to branch like that. The advantage to exceptions is they'll bust out of transactions.

def create @project.save! respond_to do |format| format.html { redirect_to(edit_project_url(@project), :notice => '#{user.name} added to #{role}.') } format.js end rescue ActiveRecord::RecordInvalid respond_to do |format| format.html { render :action => "edit" } format.js #... end end 

You'll find that it gets really tricky to wrangle your way out of a pile of nested if statements when trying to save more than one object at a time, but a simple rescue for exceptions will handle it neatly.

def create Project.transaction do @project.save! @something_else.save! @other_stuff.save! end # ... rescue ActiveRecord::RecordInvalid # ... end 

If any one of those saves blows up you'll get an exception. To ensure that all of them are displaying validation errors you might have to call .valid? on each to prime them or you will have those after the failure left untested.

Sign up to request clarification or add additional context in comments.

3 Comments

This seems a good idea, but why scaffold does not go this way? Also I assume you recommend to use rescue_action if there are several such methods?
Ok, I am going to assume you meant a rescue_from or rescue_action_in_public handler for multiple methods, in which case Chubas reply here is a subset of this one and I should accept this one as an answer.
As a general rule I use rescue_from for things that cannot be easily recovered from, and rescue when I can handle it. When a create fails, typically you just render the new form again. Something more abstract generally returns a pretty "Uh oh" page.
3

It's not a bad thing to use the if @object.save pattern. However, if you are doing exactly the same for all your actions on your controller, you can define a rescue_from action.

Something like

class MyController < ActionController::Base rescue_from ActiveRecord::RecordInvalid do render :action => edit end end 

2 Comments

Yep, that was one of my options, but this kind of needs ! version, does not it? Do you know why scaffold does not go this way by default? It seems better to me.
Your and and @tadman both seem to complement each other, so I would accept both if I could, but unfortunately I had to chose one.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.