I have a folder structure like this:
app/
models/
bar/
foo.rb
connection.rb
foo.rb
connection.rb is an "abstract class" for connecting to another database, so:
class Bar::Connection < ActiveRecord::Base
self.abstract_class = true
establish_connection "outsidedb_#{Rails.env}"
end
bar/foo.rb is for accessing the foos table from outsidedb, so:
class Bar::Foo < Bar::Connection
end
And foo.rb is for accessing the foos table from the app's db, so:
class Foo < ActiveRecord::Base
end
From the rails console if I do Foo.first or Bar::Foo.first things behave as a I would expect in that I get the first entry from the foos table of the app db and the external db, respectively.
However, if I try to access Foo from within bar/foo.rb I get the following:
class Bar::Foo < Bar::Connection
def self.test
Bar::Foo.first #=> works
Foo.first #=> NameError: uninitialized constant Bar::Foo::Foo
end
def self.other_test
Foo.parent #=> Object
Foo.superclass #=> ActiveRecord::Base
Object::Foo.first #=> works
ActiveRecord::Base::Foo.first #=> works, but with "warning: toplevel constant
# Foo referenced by ActiveRecord::Base::Foo
end
end
I can obviously get things working, but I'm looking for a sounder understanding of what's going on. I'm assuming I'm missing something between Ruby's constant/class evaluation and Rail's builtin auto-loading...
.parent returning (not the 'parent' class)?.test, but I don't get it in the rails console?Object::Foo seem to work? Is it the right thing to do?ActiveRecord::Base::Foo work, but with a warning?foo.rb classes?I'm on Rails '3.2.13' and Ruby 1.9.3-p194, just so you know!
Your problem can be fixed with
::Foo.first
Here ::Foo indicating the class Foo in top namespace.
You problem comes from the fact, that there is another Foo class in the namespace (Bar) you are working in. So you should be explicit.
As to the question why Object::Foo works (with warnings), it's a (less) known behaviour of name lookup in Ruby. Please see this article for more details.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With