So I’ve inherited a legacy application and I’m trying to work around the
edges as I put an admin tool interface on top of the existing code base.
I install Devise for user authentication, since I’ve used it in the
past. I change none of the default code. And yet, on successful sign
in, I get an error:
Render and/or redirect were called multiple times in this action. Please
note that you may only call render OR redirect, and at most once per
action. Also note that neither redirect nor render terminate execution
of the action, so if you want to exit an action after redirecting, you
need to do something like “redirect_to(…) and return”.
Here’s the thing, look where that error was thrown
render' vendor/bundle/ruby/1.9.1/gems/actionpack-3.1.0/lib/action_controller/metal/instrumentation.rb:40:inblock (2 levels) in render’
block in ms' /Users/dmorin/.rvm/rubies/ruby-1.9.3-p0/lib/ruby/1.9.1/benchmark.rb:295:inrealtime’
ms' vendor/bundle/ruby/1.9.1/gems/actionpack-3.1.0/lib/action_controller/metal/instrumentation.rb:40:inblock in render’
Look at that last line – the status method of the
application_controller. This is an addition from the legacy code, a
simple monitoring method they installed so that the app responds to a
“/status” call with the text “UP”.
I know this to be the problem because if I no longer extend the
ApplicationnController and go straight to ActionController::Base
instead, thus avoiding that status method, then this error goes away.
I’m guessing that the problem goes a little something like this,
“Successful login wants to do a redirect, but then control moves on to
the status method which tries to do a render, and throws that
DoubleRender error.” Take out the extra render, and it works.
What I can’t figure out for the life of me is how Devise is getting
there in the first place!
The problem is coming from the SessionsController#create method, but
this is just the stock version I’ve done nothing do it:
resource = warden.authenticate!(:scope => resource_name, :recall =>
set_flash_message(:notice, :signed_in) if is_navigational_format?
respond_with resource, :location => after_sign_in_path_for(resource)
This is Devise 2.0.0 on a Rails 3.1 app, Ruby 1.9.2p136. I’m just
realizing, as I go googling around, just how new this version of Devise
is. I may need to back out a bit.