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
精彩评论