Strange Issue w/ incorrect controller invocation for nested routes using the same controller name

Hi, I’ve been battling a very strange and irritating bug for a long
time now. The issue is the following:

I have namespaced my controllers in routes.rb

  • map.resources :login, :collection => [:login, :logout]
  • map.namespace :partner do |p|
    p.resources :login, :collection => [:login, :logout]
    end

As such, I have two distinct controllers app/controllers/
login_controller and app/controllers/partner/login_controller.

I’m running Apache + Passenger 2.0.3. When apache is freshly
restarted, requests to /partner/login invoke the proper controller.
However, after some period of time (or some series of
actions…whatever it is, I cannot isolate it), the wrong controller
will be invoked when requesting /partner/login.

Reaching back into my logs, I see no difference in the logging that
rails performed.

*** Log entry before bug starts showing up

Processing LoginController#index (for xx.xx.xx.xx at 2008-11-24
10:33:26) [GET]
Session ID: bb63a070c1fa56a703018fa922359146
Parameters: {“action”=>“index”, “controller”=>“partner/login”}
Rendering template within layouts/application
Rendering partner/login/index
Completed in 0.00188 (531 reqs/sec) | Rendering: 0.00178 (94%) | DB:
0.00180 (95%) | 200 OK [https://myapp/partner/login]

*** Log entry after bug has started showing up

Processing LoginController#index (for xx.xx.xx.xx at 2008-11-24
12:26:35) [GET]
Session ID: 5bdeff99bd72fe94cb8b80fd9b6beff6
Parameters: {“action”=>“index”, “controller”=>“partner/login”}
Rendering template within layouts/static_dashboard
Rendering login/index
Completed in 0.00286 (349 reqs/sec) | Rendering: 0.00274 (95%) | DB:
0.00429 (150%) | 200 OK [https://myapp/partner/login]

What kills me is that in parameters, the proper controller/action are
being identified. But if you look at the succeeding lines, you’ll see
different templates being rendered.

This has been happening to me for quite a while. Even prior to moving
to Passenger quite a while ago, I saw this same bug crop up in
production when using a mongrel_cluster solution behind Pound. So I’m
fairly certain that it’s not related to Passenger. I have not seen it
arise in my local dev environment (running mongrel).

I realize this is quite the shot in the dark, but I was curious if
anyone had any thoughts whatsoever on the source of this problem, or
if you’ve encountered anything similar in the past.

Thanks for any help.

-John

Also, worth noting that the app is running rails 2.1.0 currently. I
also had this problem when it was previously running 2.0.2. Upgrading
to 2.1.2 is potentially an option, but I’m wary of just trying
something like that in production when I don’t fully understand what
the problem is, so I’m holding off on that in the meantime.

-John

On 24 Nov 2008, at 17:41, John T. wrote:

Also, worth noting that the app is running rails 2.1.0 currently. I
also had this problem when it was previously running 2.0.2. Upgrading
to 2.1.2 is potentially an option, but I’m wary of just trying
something like that in production when I don’t fully understand what
the problem is, so I’m holding off on that in the meantime.

Are the classes both named LoginController or is one of them
Partner::LoginController ?

Fred

On 24 Nov 2008, at 18:31, John T. wrote:

end

Wonder if wrapping the other in module Partner instead of prefixing
the classname with the module would have any effect…

I suspect the complexities of how automatic constant loading work
means that if Partner::LoginController isn’t loaded but
LoginController is then it would find the wrong one. using
require_dependency (eg in application.rb) in forcing rails to load
both controllers might help.

Fred

One is defined like:

class Partner::LoginController < ApplicationController

end

The other is defined like:

class LoginController < ApplicationController

end

Wonder if wrapping the other in module Partner instead of prefixing
the classname with the module would have any effect…

-John

On Nov 24, 1:02 pm, Frederick C. [email protected]

Sent from my iPhone

On 24 Nov 2008, at 19:06, John T. [email protected] wrote:

end

Should those calls be inside or outside of the ApplicationController?
Also, are the paths correct, or should I fully prefix them with
RAILS_ROOT?

Outside the class and you don’t need a path or anything

I’ve never directly invoked require_dependency before…for what
purposes do you find it useful (aside from a potential solution to my
struggles)?

It’s like require but plays nicely with the dependencies system. Use
it whenever you’re requiring something that could be magically loaded
(models, controllers etc)

Hey Frederick,

When I place the require_dependency statements above my
ApplicationController reference, the initial start of the server blows
up. This sort of makes sense to me, because as application.rb is
loaded, it will encounter the require_dependency lines first, which I
believe will try to load those other controllers. Since, at this
point in time, ApplicationController is undefined, LoginController and
Partner::LoginController will both fail because ApplicationController
(their base class) has yet to be defined.

Make sense?

Should I put these require_dep lines beneath it? This seems to do the
trick (at least in the short-term).

For your (and everyone else’s) edification, I think this is going to
work. I noticed, as I’ve been working with this on a staging server
today, that the bug seemed to crop up when I re-deployed. In other
words, fresh deploy (w/ clean apache restart), we’re in good shape.
Successive deploy (with app restart via touch tmp/restart.txt), we see
the error. So perhaps it is a passenger-related bug (although I can
definitely recall this happening with a mongrel_cluster solution in
the past as well).

Well I chucked those two require_dependency lines at the bottom of
application.rb, redeployed (without restarting apache), and voila, the
partner/login page was now loading properly (after failing prior to
the redeployment). So I have my fingers crossed that I haven’t merely
been tricked (or rather convinced myself this is the solution) in the
interim.

Thanks for the guidance Frederick!

-John

On Nov 24, 2:35 pm, Frederick C. [email protected]

So, to be clear, you’re suggesting that I place the following at the
top of my application.rb file?

class ApplicationController < ActionController::Base
require_dependency ‘partner/login_controller’
require_dependency ‘login_controller’

end

Should those calls be inside or outside of the ApplicationController?
Also, are the paths correct, or should I fully prefix them with
RAILS_ROOT?

I’ve never directly invoked require_dependency before…for what
purposes do you find it useful (aside from a potential solution to my
struggles)?

Thanks so much!

-John

On Nov 24, 1:45 pm, Frederick C. [email protected]

Yeah beneath would be better. You just need to ensure they’re loaded
early enough

Sent from my iPhone