Does Devise make use of a "status" method? Weird bug.

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

vendor/bundle/ruby/1.9.1/gems/actionpack-3.1.0/lib/action_controller/metal/rendering.rb:15:in
`render'
vendor/bundle/ruby/1.9.1/gems/actionpack-3.1.0/lib/action_controller/metal/instrumentation.rb:40:in
`block (2 levels) in render'
vendor/bundle/ruby/1.9.1/gems/activesupport-3.1.0/lib/active_support/core_ext/benchmark.rb:5:in
`block in ms'
/Users/dmorin/.rvm/rubies/ruby-1.9.3-p0/lib/ruby/1.9.1/benchmark.rb:295:in
`realtime'
vendor/bundle/ruby/1.9.1/gems/activesupport-3.1.0/lib/active_support/core_ext/benchmark.rb:5:in
`ms'
vendor/bundle/ruby/1.9.1/gems/actionpack-3.1.0/lib/action_controller/metal/instrumentation.rb:40:in
`block in render'
vendor/bundle/ruby/1.9.1/gems/actionpack-3.1.0/lib/action_controller/metal/instrumentation.rb:81:in
`cleanup_view_runtime'
vendor/bundle/ruby/1.9.1/gems/activerecord-3.1.0/lib/active_record/railties/controller_runtime.rb:24:in
`cleanup_view_runtime'
vendor/bundle/ruby/1.9.1/gems/actionpack-3.1.0/lib/action_controller/metal/instrumentation.rb:39:in
`render'
app/controllers/application_controller.rb:9:in `status'

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:

  # POST /resource/sign_in
  def create
    resource = warden.authenticate!(:scope => resource_name, :recall =>
"#{controller_path}#new")
    set_flash_message(:notice, :signed_in) if is_navigational_format?
    sign_in(resource_name, resource)
    respond_with resource, :location => after_sign_in_path_for(resource)
  end

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.

Duane,

Try running "rake routes" in order to see which controller is being
used for the create method. Hopefully that'll help narrow things down.

Best,

Mike

What comes next in the trace? That should tell you where status is
being called from.
One thought, I wonder whether this status is overriding another one,
possibly in devise?

Also check in development.log (if you have not already done so) to
check what is happening before it fails.

Colin

Colin Law wrote in post #1043418:

need to do something like "redirect_to(...) and return".
`realtime'
app/controllers/application_controller.rb:9:in `status'

What comes next in the trace? That should tell you where status is
being called from.
One thought, I wonder whether this status is overriding another one,
possibly in devise?

Also check in development.log (if you have not already done so) to
check what is happening before it fails.

Colin

Ok, well now I'm really confused. It appears to have more to do with a
"create and redirect" than with Devise, because it just happened to me
on one of my own controllers. Here's the interesting bit in the middle:

app/controllers/application_controller.rb:9:in `status'
vendor/bundle/ruby/1.9.1/gems/actionpack-3.1.0/lib/action_controller/metal/instrumentation.rb:64:in
`block in redirect_to'
vendor/bundle/ruby/1.9.1/gems/activesupport-3.1.0/lib/active_support/notifications.rb:53:in
`block in instrument'
vendor/bundle/ruby/1.9.1/gems/activesupport-3.1.0/lib/active_support/notifications/instrumenter.rb:21:in
`instrument'
vendor/bundle/ruby/1.9.1/gems/activesupport-3.1.0/lib/active_support/notifications.rb:53:in
`instrument'
vendor/bundle/ruby/1.9.1/gems/actionpack-3.1.0/lib/action_controller/metal/instrumentation.rb:60:in
`redirect_to'
app/controllers/ui/campaigns_controller.rb:48:in `block (2 levels) in
create'

My code (campaigns_controller line 48) is just typical auto-generate
scaffold code:

        format.html { redirect_to @ui_campaign, notice: 'Campaign was
successfully created.' }

I have no idea what's going on in the middle with all that metal stuff,
or how it ends up on status.

I wonder whether it could be that status is now a reserved word. I
would rename that action and if you want to keep it the same
externally then map it to the new action in routes.rb.

Colin

I wonder whether it could be that status is now a reserved word. I
would rename that action and if you want to keep it the same
externally then map it to the new action in routes.rb.

Excellent idea, I change the method to status_monitor and have the
/status route pointing to that so nobody's the wiser. Good deal.

Can you tell me when status became a reserved word? I'd like to document
it appropriately so that when the rest of the legacy apps here that use
a similar monitoring method want to upgrade, they won't hit the same
problem.

Thanks!

I wonder whether it could be that status is now a reserved word. I
would rename that action and if you want to keep it the same
externally then map it to the new action in routes.rb.

Excellent idea, I change the method to status_monitor and have the
/status route pointing to that so nobody's the wiser. Good deal.

Can you tell me when status became a reserved word? I'd like to document
it appropriately so that when the rest of the legacy apps here that use
a similar monitoring method want to upgrade, they won't hit the same
problem.

No idea, I just thought that might be a possibility. You could try
searching through the code.

Colin