开发者

Rails exception handling when submitting a form

I want to know what is the best method to handle an exception that occurs when saving a model during a form submit. I am currently using a code snippet like this.


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

And here is my view named 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%>

My understanding about the above code snippet is that render method does not call the a开发者_运维技巧ction 'edit' before calling the template 'edit'. I am passing an object(@permissions) from the action handler for 'edit' to the template 'edit'. Things work fine when I do a redirect to the edit action but not during render as the object(@permissions) that I have passed from the controller to the template is not available during render. Am I doing things right? Is this the Rails way to handle exceptions? If so, how can I pass an object(@permissions) to the template when I call render method? Any pointers will be greatly appreciated.

Thanks.


This code is redundant:

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

update_attributes will also save, so the call to save! isn't doing anything. The more idiomatic way to do it in rails is like this:

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

Is there some reason you need to be raising an exception when the save can't complete?


You are calling save! and update_attributes! methods and these methods will raise an ActiveRecord exception if any of the validations fail. Also your code is redundant in doing update_attributes! and save!. You are better to write this methods in the traditional scaffold way.

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

Actually you can make your life easier by declaring customer as a resource in the routes.rb(map.resources :customer in Rails 2.3.5) and naming the submit_handler method to create as this will follow the restful routing as advocated by Rails.


Have a look here for info about how to rescue exceptions raised in controller actions: http://apidock.com/rails/v2.3.8/ActiveSupport/Rescuable/ClassMethods/rescue_from

0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜