Rails 中的命名空间模型生成 NameError:未初始化的常量 [英] Namespaced model in Rails generating NameError: uninitialized constant

查看:40
本文介绍了Rails 中的命名空间模型生成 NameError:未初始化的常量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有这样的文件夹结构:

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.firstBar::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...

  1. 什么是 .parent 返回(不是父"类)?
  2. 为什么我在 .test 中得到错误,但在 rails 控制台中却没有得到它?
  3. 为什么 Object::Foo 似乎有效?这是正确的做法吗?
  4. 为什么 ActiveRecord::Base::Foo 可以工作,但有警告?
  5. 除了重命名我的一个 foo.rb 类之外,还有更多的方法可以完成我所做的事情吗?
  1. What is .parent returning (not the 'parent' class)?
  2. Why do I get the error in .test, but I don't get it in the rails console?
  3. Why does Object::Foo seem to work? Is it the right thing to do?
  4. Why does ActiveRecord::Base::Foo work, but with a warning?
  5. 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆