Rails中的Namespaced模型生成NameError:uninitialized constant

时间:2015-09-29 20:59:13

标签: ruby-on-rails ruby ruby-on-rails-3 namespaces

我有一个像这样的文件夹结构:

app/
  models/
    bar/
      foo.rb
      connection.rb
    foo.rb

connection.rb是用于连接到另一个数据库的“抽象类”,所以:

class Bar::Connection < ActiveRecord::Base
  self.abstract_class = true
  establish_connection "outsidedb_#{Rails.env}"
end

bar/foo.rb用于从foos访问outsidedb表格,因此:

class Bar::Foo < Bar::Connection
end

foo.rb用于从应用程序的数据库访问foos表,所以:

class Foo < ActiveRecord::Base
end

如果我执行Foo.firstBar::Foo.first,那么从rails控制台执行的操作就像我期望的那样,我从app db的foos表中获取第一个条目db,分别。

但是,如果我尝试从Foo内访问bar/foo.rb,我会收到以下信息:

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的内置自动加载之间缺少某些内容......

  1. 什么是.parent返回(不是'父级')?
  2. 为什么我在.test中收到错误,但我没有在rails控制台中收到错误?
  3. 为什么Object::Foo似乎有效?这是正确的做法吗?
  4. 为什么ActiveRecord::Base::Foo有效,但有警告?
  5. 如果不重新命名我的foo.rb类之一,还有更多的方法可以完成我的工作吗?
  6. 我正在Rails '3.2.13'Ruby 1.9.3-p194,只是你知道!

2 个答案:

答案 0 :(得分:2)

您的问题可以通过

解决
::Foo.first

此处::Foo表示顶级命名空间中的类Foo

你的问题来自于你正在使用的命名空间(Foo)中有另一个Bar类。所以你应该是明确的。

关于为什么Object::Foo有效(带警告)的问题,它是Ruby中名称查找的(较少)已知行为。有关详细信息,请参阅this文章。

答案 1 :(得分:1)

以下是有关.parent方法的一些文档,可帮助回答您的第一个问题:http://guides.rubyonrails.org/active_support_core_extensions.html#extensions-to-module-parents。向下滚动到第3.3节,了解相关部分。

.parent方法附带Active Support,它为Ruby on Rails组件提供Ruby扩展。 .parent方法是Modules的扩展,它返回包含当前类的模块的名称。因此,如果您执行了Bar::Foo.parent,则返回值应为Bar

但是,当类没有封闭模块时,返回值将默认为Object。这是Foo.parent执行时发生的事情,因为此处Foo指的是不在Foo命名空间中的Bar类。

相关的Rails魔术:https://github.com/rails/rails/blob/c9bbac46ddfc68caff6cd8a95c8d0fd045bd9201/activesupport/lib/active_support/core_ext/module/introspection.rb