带有名称空间或预期行为的ActiveRecord错误?

问题描述 投票:1回答:1

Rails 4.1.16

Ruby 2.2.7

我有这个ActiveRecord模型:

class Something::Type < ActiveRecord::Base

参考这样的模型时:

Something::Type.find_by_whatever("test")

我收到以下错误:

NoMethodError: undefined method `find_by_whatever' for ActiveRecord::AttributeMethods::Serialization::Type:Class

[我了解Ruby常量已分解,因此Type作为其自己的常量存在,并且自动加载器首先找到ActiveRecord::AttributeMethods::Serialization::Type

但是,以“绝对”方式引用名称空间(以冒号作为前缀)应该可以解决此问题,但是结果是相同的。有什么想法吗?

::Something::Type.find_by_whatever("test")

NoMethodError: undefined method `find_by_whatever' for ActiveRecord::AttributeMethods::Serialization::Type:Class
ruby-on-rails ruby ruby-on-rails-4 autoload autoloader
1个回答
0
投票

使用范围结果运算符定义类时的问题是,模块嵌套已解析到定义点(使用module关键字的点)。如果您查看模块嵌套:

class Something::Type < ActiveRecord::Base
  puts Module.nesting.inpsect # [Something::Type]
end

该类甚至没有真正嵌套在Something模块中。这将给您一个非常令人惊讶的不断查找:

module Something
  FOO = "test"
end

class Something::Type
  puts Foo # gives a uninitialized constant error since its not looking in the Something module
end

相反,您应该始终使用显式嵌套声明命名空间的类:

module Something
  class Type
    puts Module.nesting.inspect # [Something::Type, Something]
    puts Foo  # test
  end
end

这将为模块嵌套[Something::Type, Something],这意味着它将在相同的Something命名空间中正确查找常量。

[这是旧的经典自动装带器依赖于monkeypatching Module#const_missing趋向于掩盖的东西。 Zeitwork并没有做到这一点。

© www.soinside.com 2019 - 2024. All rights reserved.