Ruby (Rails) constant lookup precedence

Recently I’ve been running into an interesting problem (at least, to me). Within a web application I am working on I found what I thought was a sporadic error occurring, which resulted in the need to restart Apache in order to temporarily fix it. That was, until I made a change to the controller and thus the issue appeared again, until I restarted Apache. The error:

uninitialized constant Frontend::User::ForgottenPasswordController::User

This puzzled me for quite a while, but I continued to develop while every now and again I would come up against this and look for answers. I found nothing, but knew the following:

  • User constant (model class) exists and works fine
  • This only happened in specific controllers

Jumping onto and having a chat with `workmad3` we solved the problem, and it’s a pretty simple one, once you understand how Ruby and thus Rails references constants.

Changing my reference to the User constant to ::User told Ruby to look for the constant in the global namespace. This worked and no longer did I run into the uninitialized constant error.

As it turns out, Ruby will look for the constant when called within a namespace from the top of the namespace down, so in this case:

* Frontend::User::ForgottenPasswordController
* Frontend::User
* Frontend
* `Global namespace`

As you can see, as I had namespaced the controller with User (as the second namesapce) Ruby was returning an error because `Frontend::User` did not exist as a constant, but was technically what I was referencing as it didn’t get down to the global namespace. Placing the double collons in-front of the constant tells Ruby to look for it in the global namespace.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>