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
    @userEvents = current_user.event
    @event = @userEvents.find(params[:id])
  rescue ActiveRecord::RecordNotFound  
    redirect_to :controller => "main", :action => "index"
  end
  respond_to do |format|
    format.html # show.html.erb
    format.json { render json: @event }
  end
end
If the event is not found for the user it means he played with the URL and the event he is trying to get does not belong to him. I want to either redirect him to the main page or just display the page with an error that the event is not found. If I try to run the code above this error fires:
AbstractController::DoubleRenderError in EventsController#show 
What's the best way to fix this?
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
                        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.
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: ""
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With