Rails Namespaces Rock. Rails Namespaces Suck.

So this evening (can we still call it evening at 4:30am?) I encountered a frustrating issue. I’m working on a rails site for a photographer friend and it’s been coming along rather smoothly. However, tonight I ran into an annoyingly frustrating issue that turns out to have been caused some routes namespace gotchas.

Let me explain:

The site I’m putting together has an admin section, a client section and (of course) a public section. It only seems logical to namespace the different sections of the site for pretty urls and easier controller management. With that in mind, I needed a few controllers to handle the three sections. So, for instance, I had PicturesController, Client::PicturesController and Admin::PicturesController. And here’s what I initially had in my routes.rb file to handle the routing:


  map.namespace :client do |client|
    client.resources :pictures, :member => { :approve => :put, :reject => :put }
    client.resources :albums, :has_many => [:pictures]
  end

  map.namespace :admin do |admin|
    admin.resources :pictures, :collection => {:bulk_edit => :put, :bulk_update => :post}
    admin.resources :albums
    admin.resources :clients, :has_many => [:pictures, :albums]
  end

  # and of course the default
  map.connect ':controller/:action/:id'

With those namespaces in place, I aught to have been able to navigate to the following urls with no problem:


/admin/pictures/*
/client/pictures/*
/pictures/*
/admin/albums/*
/client/albums/*

And, when running things locally, I could. Not only that, when the app was running in production mode on the server, I could navigate to those URLs without problem as well…sometimes. But every once in a while (and it seemed to become more frequent the longer the mongrel process had been running), I would get a 404 error in the browser. You could usually get through to the actual page by refreshing a few times, but who wants to (or should have to) to that?! Frankly, it was pissing me off. On to the logs…

Checking the production.log was no help — ActionController::UnknownAction (No action responded to index) — really?! really?! Because I’m looking at the index action right now. Don’t try to tell me that it’s not there!

So, since production.log wasn’t playing by my rules, I decided to peruse the mongrel log. And this is what I found:

warning: toplevel constant PicturesController referenced by Admin::PicturesController

It was a warning I had never seen before. A little strange, but basically the toplevel PicturesController was stepping on the Admin::PicturesController’s toes, stomping all up and down on its methods. It’s a strange thing, but apparently there are issues with route namespaces in rails. To be honest though, I’m not sure it’s a flaw in Rails—it may be the nature of Ruby and the fact that you can’t have a class and a module of the same name. Either way, it was a frustrating thing to try and figure out. Eventually I found a bit of direction via a thread in the Ruby on Rails Google group (http://groups.google.com/group/rubyonrails-talk/browse_thread/thread/e4a1e5f532f53785/f9a982286459d74c?lnk=raot).

All’s well that ends well, but I have to say, this one was a doozy—it’s always a pain to track down a bug that can’t be reproduced locally and also happens only intermittently. Hope this is helpful to someone.

And I’m still not tired…

UPDATE: I just realized I didn’t mention what the solution was to this problem. Basically, just rename your controllers so that they each have a unique name (this could be as simple as making one singular and the other plural). Kind of annoying, but it’s a pretty easy solution to a very frustrating problem.

Posted by Phil Burrows, Rails Developer on Friday, May 02, 2008