I have an app with user and events. Each user has several events. When a user wants to see a specific event he will get to this action:
def show
begin
@use
Put return after redirect
begin
@userEvents = current_user.event
@event = @userEvents.find(params[:id])
rescue ActiveRecord::RecordNotFound
redirect_to :controller => "main", :action => "index"
return
end
In application controller, please write:
rescue_from (ActiveRecord::RecordNotFound) { |exception| handle_exception(exception, 404) }
protected
def handle_exception(ex, status)
render_error(ex, status)
logger.error ex
end
def render_error(ex, status)
@status_code = status
respond_to do |format|
format.html { render :template => "error", :status => status }
format.all { render :nothing => true, :status => status }
end
end
Create a page error.html.erb
<div class="page-header">
<h1>
<%= t "errors.#{@status_code}.heading" %>
<small><%= t "errors.#{@status_code}.subheading" %></small>
</h1>
</div>
<p><%= t "errors.#{@status_code}.description" %></p>
<% if defined? root_path %>
<%= link_to t(:return_to_home), root_path %>
<% end %>
and in en.yml
en:
errors:
"404":
description: "The page you are looking for does not exist!"
heading: "Record not found"
subheading: ""
Calling redirect_to
doesn't return from your action method which is why moving on to the respond_to
block causes the DoubleRenderError
. One way to fix that is with:
redirect_to :controller => "main", :action => "index" and return
However, a better solution might be to either rescue from this exception declaratively or just let it propagate to the client. The former look like this:
class YourController < ActionController::Base
rescue_from ActiveRecord::RecordNotFound, with: :dude_wheres_my_record
def show
# your original code without the begin and rescue
end
def dude_where_my_record
# special handling here
end
end
If you just let the exception fester the user will see the public/404.html
page in production mode.