2011-03-18 72 views
0

我想知道处理在表单提交期间保存模型时发生的异常的最佳方法。我目前正在使用这样的代码片段。提交表单时的Rails异常处理


class Mycontroller 
    def edit 
    @customer = Customer.new 
    @permissions = Hash.new 
    @permissions['save'] = true 
    @permissions['clear'] = true 
    @permissions['some_other'] = false 
    end 

    def submit_handler 
    @customer = Customer.find(params[:id]) 
    @customer.update_attributes!(params[:customer]) 
    redirect_to(:controller => 'XXXXXX', :action => 'edit', :id=>params[:id]) 
    rescue ActiveRecord::RecordInvalid => e  
    render :action => :edit, :id => params[:id] 
    end 
end 
 

,这里是我的看法命名edit.html.erb

<% form_for :customer, :url => {:action =>"submit_handler", :id=>id} do |acc|%> 
<%= render :partial => 'fields', :locals => { :acc => acc } %> 
<table align="center"> 
<tr align="center"> 
<% if @permissions['some_other'] == true %> 
<td id='some_other' align="center"><%= submit_tag "Some other" %></td> 
<%end%> 
<% if @permissions['save'] == true %> 
<td id='save'align="center"><%= submit_tag "Save" %></td> 
<%end%> 
<% if @permissions['clear'] == true %> 
<td id='clear' align="center"><%= button_to "Clear", :action => :clear %></td> 
<%end%> 
</table> 
<%end%> 

我对上面的代码片断的理解是,渲染方法调用模板之前不会调用动作“编辑”“编辑”。我将“编辑”的操作处理程序中的对象(@permissions)传递给模板“编辑”。事情工作正常时,我做了重定向到编辑操作,但不是在渲染过程中,因为我已经从控制器传递给模板的对象(@权限)在呈现期间不可用。我做对了吗?这是Rails处理异常的方式吗?如果是这样,当我调用render方法时,如何将对象(@permissions)传递给模板?任何指针将不胜感激。

谢谢。

+0

究竟发生了什么错误?如果在'edit'函数和视图(表单)中命名对象'@ customer',则不会收到错误,因为'@ customer'对象也是在'submit_handler'动作中创建的。.. – rubyprince 2011-03-18 17:06:28

+0

@rubyprince :我编辑了代码以使其更清晰。让我知道这是否有助于理解我的问题。谢谢你的努力。 – rajaramyadhav 2011-03-18 17:20:18

回答

2

此代码是多余的:

@customer.update_attributes!(params[:customer]) 
@customer.save! 

update_attributes也将节省,所以调用save! ISN”不要做任何事情。更地道的方式做到这一点的轨道是这样的:

def submit_handler 
    @customer = Customer.find(params[:id]) 

    # Update your attributes 
    if @customer.update_attributes(params[:customer]) 
    # Redirect on success 
    redirect_to(:controller => 'XXXXXX', :action => 'edit', :id=>params[:id]) 
    else 
    # Render the action template -- no need to reset the ID here 
    render :action => :edit 
    end 
end 

是有一些原因,你必须抛出一个异常时保存不能完成?

+0

对不起我添加@ customer.save!的错误。它实际上并不存在于原始代码中。实际的代码要复杂得多。该表格包含多个模型,全部保存在单个事务中。我试图给出我的问题的简化版本。有了控制器中的事务逻辑,我想我唯一的办法就是引发一个异常。有没有办法将@permission对象传递给模板? – rajaramyadhav 2011-03-18 17:40:58

+0

如果您想将'@ permissions'对象传递回您'else'条件下的视图,则需要重建它(因为它不再作为控制器上的实例变量存在)。有几种方法可以做到这一点。就个人而言,除非这些字段需要一些额外的安全性,否则我只是将它们作为'hidden_​​field_tag'存储,然后重置'else'块中的值。否则,你可以把它们藏在'session'中。 – jerhinesmith 2011-03-18 18:01:53

+1

另外,如果您要保存多个对象,您可能需要查看一些涵盖此主题的Railscast:http://railscasts.com/episodes/196-nested-model-form-part-1 – jerhinesmith 2011-03-18 18:09:54

1

您正在调用save!update_attributes!方法,如果任何验证失败,这些方法将引发ActiveRecord异常。此外,您的代码在执行update_attributes!save!时是多余的。你最好用传统的脚手架方式写这种方法。

class Mycontroller 
    def submit_handler 
    @customer = Customer.find(params[:id])   
    if @customer.update_attributes(params[:customer]) 
     redirect_to(:controller => 'XXXXXX', :action => 'edit', :id=>params[:id]) 
    else 
     get_edit_permissions()  
     render :action => :edit 
    end 
    end 

    def edit 
    @customer = Customer.find(params[:id]) 
    get_edit_permissions() 
    end 

    def get_edit_permissions 
    @permissions = Hash.new 
    @permissions['save'] = true 
    @permissions['clear'] = true 
    @permissions['some_other'] = false 
    # @permissions = {'save' => true, 'clear' => true, 'some_other' => false} 
    end 
end 

其实你可以让你的生活更轻松(用Rails 2.3.5 map.resources :customer)在routes.rb中宣布customer作为一种资源和命名submit_handler方法create,因为这将遵循宁静的路由通过提倡轨。

+0

对不起我添加@ customer.save!的错误。它实际上并不存在于原始代码中。实际的代码要复杂得多。该表格包含多个模型,全部保存在单个事务中。我试图给出我的问题的简化版本。有了控制器中的事务逻辑,我想我唯一的办法就是引发一个异常。有没有办法将@permission对象传递给模板? – rajaramyadhav 2011-03-18 17:41:43

+0

@jerhinesmith说,你还必须在'submit_handler'动作中重新创建'edit'重建中使用的变量。您可以将其设置为独立的方法,并在'edit'和'submit_handler'中调用它。我已更新我的帖子。 – rubyprince 2011-03-19 01:26:55