Rails Newbie:控制器中错误处理的建议

时间:2010-10-27 15:13:27

标签: ruby-on-rails ruby ruby-on-rails-3 error-handling design-guidelines

对不起,如果问题很明显,我只是开始使用Rails 我现在在几个控制器方法中有以下代码:

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

所以问题是,在所有方法中对错误做同样事情的最佳方法是什么? 是否建议我使用save!并在rescue_action处理?

或者我应该使用自己的respond方法并在块中传递save吗?

2 个答案:

答案 0 :(得分:16)

在块中稍后使用保存和救援的异常提升变体通常比这样分支更方便。例外的好处是它们会破坏交易。

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

你会发现在尝试一次保存多个对象时,从一堆嵌套的if语句中解决问题变得非常棘手,但对于异常只有一个简单的rescue将整齐地处理它。

def create
  Project.transaction do
    @project.save!
    @something_else.save!
    @other_stuff.save!
  end

  # ...
rescue ActiveRecord::RecordInvalid
  # ...
end

如果其中任何一个保存爆炸,你将获得例外。为了确保所有这些都显示验证错误,您可能需要在每个上调用.valid?来填充它们,否则您将在未经测试失败后获得这些错误。

答案 1 :(得分:3)

使用if @object.save模式并不是一件坏事。但是,如果您对控制器上的所有操作执行完全相同的操作,则可以定义rescue_from操作。

Something like

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