Watch Your Namespace
June 30, 2006
Note: The Pages o’ Peat have moved to http://peat.org/ — please update your bookmarks and references accordingly. Thank you!
I helped a client troubleshoot a small “gotcha” in his Rails app this evening. It’s an odd problem he bumped into after refactoring a controller into a group of controllers — a particularly spiffy feature of Rails. For example, if you have a controller (say,
FooController) that’s getting rather large and unwieldy, you can break it up into smaller controllers in a
.. becomes ..
… and the controller class declaration changes from:
class FooController < ApplicationController
… to …
class Foo::BarController < ApplicationController
… and so on for
Foo::QuuxController. Pretty handy! It should be noted that the controller routing changes as well, making
Foo::BarController#my_action accessable as
So here’s the gotcha: if you’re refactoring a
FooController, chances are that you also have a
Foo model (
Foo model is declared as
class Foo, which means you’re suddenly mucking about in its namespace when you declare a controller as
Foo::BarController. You’re in trouble town with generic routing errors when you attempt to load
http://mysite.com/foo/bar/my_action, and the way out isn’t immediately apparent if you’re not specifically looking for such collisions.
The solution is to change either the controller or model namespace to something else. Controllers are a bit more flexible than models when it comes to naming, so changing
Foos::BarController and renaming the directory to
controllers/foos/bar_controller.rb fixes the problem — if you don’t mind pluralized names.