Is this error giving you a headache? Have you already tried using
and return as Rails suggests in its guides but still can’t make the error go away?
TL;DR: See if you are calling
render in controller concerns. This post will explain why this might be the issue that’s right under your nose.
The key thing to understand here is that
render has multiple implementations in Rails and we need to know which one is being used when.
# rails/actionview/lib/action_view/renderer/renderer.rb# Main render entry point shared by Action View and Action Controller.def render(context, options)
In the context of a view, the
render method can be called multiple times to render partials. No specific restrictions apply to this implementation, so no exceptions will be raised in this case.
# rails/actionpack/lib/action_controller/metal/rendering.rb# Check for double render errors and set the content_type after rendering.def render(*args) #:nodoc:
raise ::AbstractController::DoubleRenderError if response_body
When explicitly calling
render from a controller, it checks that no other
response_bodywas previously set (e.g. via
redirect_to). If there is already a
response_body, it raises
AbstractController::DoubleRenderError. On the other hand, if
response_body is empty, then everything works just fine.
Please note that explicitly calling
render in a controller action is not obligatory. In case this does not happen, then
ActionController::ImplicitRender will figure out which template to render for us.
So far so good. We now understand how the different implementations of
But, it can get tricky when trying to render partials from a controller concern. It’s true that we don’t see this very often and is probably not a good code design, but I’ve come across a situation like this when working on a project. Let’s look at the next simplified example.
Calling render inside a controller concern
Suppose there is a controller concern that exposes a
helper_method that renders a partial.
extend ActiveSupport::Concern included do
end def display_bar
render partial: 'shared/bar'
Then, a controller includes this concern.
# app/controllers/foo_controller.rbclass FooController < ApplicationController
include Bar def index
And uses its
# app/views/foo/index.html.erb<%= display_bar %>
<%= display_bar %>
Why would this raise
ActionController::DoubleRenderError? Are we not just trying to render partials multiple times? The answer would be: “Yes and no”.
If we had rendered the partials directly in the view, then no error would have been raised. That’s because we would have called
ActionView::Renderer#render and we know it has no restrictions.
But, since we are calling a
helper_method implemented in the context of a controller concern, the method will actually execute as part of the controller. It will therefore call
ActionController::Rendering#render, which we know cannot be explicitly called more than once.
Try not to call
render in controller concerns. But if you decide to do so, please be careful about