开发者

Rails Newbie: Recommendations for error handling in controller

开发者 https://www.devze.com 2023-01-22 01:23 出处:网络
Sorry if the question is obvious, I am only starting to work with Rails. I have a following code in se开发者_如何学编程veral controller methods now:

Sorry if the question is obvious, I am only starting to work with Rails.

I have a following code in se开发者_如何学编程veral 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?


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.


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
0

精彩评论

暂无评论...
验证码 换一张
取 消