Rails render and return in before_action, DoubleRenderError

10,571

Solution 1

If your intention is to render the 404 page, you shouldn't render it manually in the before_filter. The right way of doing that is raising a routing error, like this:

raise ActionController::RoutingError.new('Not Found')

You could implement a method called "render_404", raise this exception in it and let the routing system do the rest.

EDIT: Actually, your code should work. I really don't know what is going on. I wrote the same thing here and it worked - the action method is never called if the before_filter renders something. What version of Rails are you using?

Solution 2

This is a pretty simple case of flow control.

Yes, when you and return from within the method, it obviously returns and doesn't reach the second render.

Nothing about rendering inside a before_filter is meant to stop the actual invocation of the action itself, and calling and return from a before_filter doesn't affect the execution of a completely separate method invocation.

This is pure Ruby flow-control, no Rails magic involved.

Share:
10,571
brodney
Author by

brodney

Updated on June 05, 2022

Comments

  • brodney
    brodney over 1 year

    In a controller action with a before_action, using render something and return does not actually cause the controller to stop executing the rest of the action. In my testing, only when called in the controller action does and return work as I would expect.

    # DoubleRenderError
    class SomeController < ApplicationController
        before_filter :double_render, only: [:index]
    
        def index
            render file: "public/500.html", status: :internal_server_error
        end
    
        def double_render
            render file: "public/404.html", status: :not_found and return
        end
    end
    
    # Renders 404 only, no error
    class SomeController < ApplicationController
        def index
            render file: "public/404.html", status: :not_found and return
            render file: "public/500.html", status: :internal_server_error
        end
    end
    

    What's going on here? Can before_actions stop the rest of a controller's execution?

  • brodney
    brodney over 9 years
    I suspected as much. Understanding what I'm trying to accomplish, can you please provide some direction?
  • user229044
    user229044 over 9 years
    See the other answer. Raise an exception rather than rendering an error.
  • brodney
    brodney over 9 years
    I'm using rails 4.1.4.
  • sky_coder123
    sky_coder123 almost 8 years
    What if I want to render a json in a before filter with a custom error message? (I am using my controller as API provider for an app)