I have a Rails app that involves namespaced models. In /app/models/x/
y.rb
I have
class X::Y < ActiveRecord::Base
blah
blah
end
On my dev machine (OS X, ruby 1.8.6, rails 1.2.5), all works fine.
However on my production machine (Ubuntu 6.0.6 LTS, ruby 1.8.6, rails
1.2.5), the namespaced models refuse to work.
On the dev machine, I can reference the classes in script/console
Loading development environment.
X::Y
=> X::Y
If I run script/console on the production server, I get:
Loading development environment.
X::Y
NameError: uninitialized constant X
from /usr/lib/ruby/gems/1.8/gems/activesupport-1.4.4/lib/
active_support/dependencies.rb:266:in `load_missing_constant'
from /usr/lib/ruby/gems/1.8/gems/activesupport-1.4.4/lib/
active_support/dependencies.rb:452:in `const_missing'
from /usr/lib/ruby/gems/1.8/gems/activesupport-1.4.4/lib/
active_support/dependencies.rb:464:in `const_missing'
from (irb):1
I am quite perplexed by this. Other than the Ubuntu/Mac OS X
difference, the same version of ruby, rails, and all gems are
installed.
Any help or suggestions would be greatly appreciated.
Unless something has changed that I don't know about, then you're just
outta luck. You can't do namespaced models, has to do with
classloading. You'll spend tons of time and just get headaches, and
in the end find out that it simply doesn't work. I know because I
went through that about a year ago Sucks, but it is what it is.
What's weird is that on my development machine, everything runs just
peachy. I even tested it on another developer's Windows machine and it
worked fine there too.
I'd understand if it was broken everywhere, but if Rails is 100% Ruby,
and both machines are running the same version of Ruby, I don't see
why one would work and the other wouldn't.
Couldn't tell ya what the difference is. However, I will say there's
a difference between dev and production environments. Rails caches
the classloading stuff in production, and reloads it all in dev. I
spent a lot of time getting the namespaced model stuff to work in dev
and testing, and it was fine, but then when I used it in production it
blew up.
So yeah, you're right, the discrepancy is weird. But seriously, you
should only investigate more if you're interested in why it might be
different. Even once you figure that out, your code won't work in
production.
Andrew - think of that error as meaning something like "syntax error
in file X, or in something that file X referenced." It doesn't tell
you anything about the error itself.
Try the old-fashioned approach: delete almost everything from the
files in question until you get to the point where you're not seeing
that error. Start with just a couple lines - take it down to almost
literally what you posted:
class X::Y < ActiveRecord::Base
end
Does that work? "Work" here in the sense of "did you get a different
sort of error." Great - now add in half of the real contents. Repeat
as necessary.
Keep an eye out for circular dependencies. It's been a while since
I've hit that error, but I think most of the time the bug (or design
flaw) was caused by file A referred to something in B that wanted
something in A, and I had tried to play games with manual requires
that didn't play well with the Rails loader.
Pat - are you sure your thought that namespaced models don't work is
current? A year is an awfully long time. My namespaced models don't
seem to be giving me any grief these days. The only thing I can think
of is that STI can get a little weird. (You sure you're not thinking
of namespaced controllers? I've never had a reason to try that...)
After a very long night debugging, which involved freezing the rails
gems on my dev machine and production machine, inserting lots of print
statements into dependencies.rb in the ActiveSupport gem, copying the
file back and forth, and firing up script/console, and looking at
differences, etc I have finally found the solution.
It turns out that File.directory? is not case sensitive on Mac OS X
(weird I know for a UN*X based OS), while File.directory? is case
sensitive on Ubuntu. My folder inside app/models was capitalized, and
the system looks for the lower case version. Mac OS X would find the
directory, while Ubuntu didn't. Hence auto loading the module failed
so it never looked for the class in that directory.
Renamed the directory and everything works like a dream,
That’s not really all that weird. The default file system on OS X isn’t case sensitive, so it makes sense that File.directory? should base its response on whether the OS/filesystem currently in use will find the directory.
You can always use a different filesystem on your mac that is case sensitive but most of the time it’s just a potential issue that you need to keep in mind.