Rails 中的命名空间模型生成 NameError:未初始化的常量 [英] Namespaced model in Rails generating NameError: uninitialized constant
问题描述
我有这样的文件夹结构:
I have a folder structure like this:
app/
models/
bar/
foo.rb
connection.rb
foo.rb
connection.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
用于从 outsideb
访问 foos
表,所以:
bar/foo.rb
is for accessing the foos
table from outsidedb
, so:
class Bar::Foo < Bar::Connection
end
而 foo.rb
用于从应用程序的数据库访问 foos
表,因此:
And foo.rb
is for accessing the foos
table from the app's db, so:
class Foo < ActiveRecord::Base
end
如果我执行 Foo.first
或 Bar::Foo.first
,则从 rails 控制台中,事情的行为与我期望的一样,因为我从foos
分别是应用数据库和外部数据库的表.
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.
但是,如果我尝试从 bar/foo.rb
中访问 Foo
,我会得到以下信息:
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
我显然可以让事情正常进行,但我正在寻找对正在发生的事情有更深入的了解.我假设我在 Ruby 的常量/类评估和 Rail 的内置自动加载之间遗漏了一些东西...
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
返回(不是父"类)? - 为什么我在
.test
中得到错误,但在 rails 控制台中却没有得到它? - 为什么
Object::Foo
似乎有效?这是正确的做法吗? - 为什么
ActiveRecord::Base::Foo
可以工作,但有警告? - 除了重命名我的一个
foo.rb
类之外,还有更多的方法可以完成我所做的事情吗?
- What is
.parent
returning (not the 'parent' class)? - Why do I get the error in
.test
, but I don't get it in the rails console? - Why does
Object::Foo
seem to work? Is it the right thing to do? - Why does
ActiveRecord::Base::Foo
work, but with a warning? - There a more rails way to do what I've done without just renaming one of my
foo.rb
classes?
我正在使用 Rails '3.2.13'
和 Ruby 1.9.3-p194
,所以你知道!
I'm on Rails '3.2.13'
and Ruby 1.9.3-p194
, just so you know!
推荐答案
您的问题可以通过
::Foo.first
这里的 ::Foo
表示顶级命名空间中的 Foo
类.
Here ::Foo
indicating the class Foo
in top namespace.
您的问题来自这样一个事实,即您正在使用的命名空间 (Bar
) 中还有另一个 Foo
类.所以您应该明确.
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.
至于为什么 Object::Foo
工作(带有警告)的问题,这是 Ruby 中名称查找的(鲜为人知的)行为.请参阅这个文章了解更多详情.
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.
这篇关于Rails 中的命名空间模型生成 NameError:未初始化的常量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!