5

我在 lib 目录中有一个文件,它使用模型中定义的一些常量,例如:

class User < ActiveRecord::Base
   MAX_EMAIL_ADDRESS_LENGTH = 255
end

然后我在 lib/foo.rb

module Foo
  LONG_EMAIL_ADDRESS = "foo@bar.com".rjust(User::MAX_EMAIL_ADDRESS_LENGTH, "a")
end

由于找不到类用户而失败。如何在 lib 上的该文件之前加载用户?

我通过在我的 application.rb 中加载该文件:

config.autoload_paths += %W(#{config.root}/lib)
4

5 回答 5

3

第一部分做得对:

config.autoload_paths += %W(#{config.root}/lib)

接下来很重要的,模块

module Foo
  ...
end

必须放入

lib/foo.rb

文件。

然后,可以将其include写入应用程序代码。

class Comment < ActiveRecord::Base
  include Foo
  ...
end

如果foo.rb不打算包含来自 lib 目录的文件(但它可能是错误的方式),那么要在此代码中使用 Rails 模型和其他内容,您应该将其放入 foo.rb:

require_relative "../config/environment.rb"
于 2012-07-24T18:46:46.680 回答
3

解决方案是,我在 /lib 中的文件实际上是 rake 文件所需要的,并且似乎在 Rails 设置整个自动加载系统之前加载了 rake 文件,因此找不到模型。从 .rake 文件中删除要求后,一切都开始工作了。

于 2012-07-25T06:24:11.573 回答
3

我知道这是一个老问题,但我刚刚遇到同样的问题,经过一些搜索,我找到了解决方案,所以我认为值得分享。

我想在我的 /lib 目录中的一个必需文件中使用模型“Foo”。首先,我这样做了,但没有奏效:

# in my rake file
task :foo_task do
  require /some_path/lib/bar.rb
end

# in /lib/bar.rb
puts "Foo = #{Foo.count} "

# => uninitialized constant Foo

经过一番搜索,我发现要访问我的 lib 文件中的模型,我需要在我的任务中指定环境。所以我只是将它添加到我的任务声明中:

task :foo_task => [:environment] do

现在,当我调用我的任务时,它正确放置了 Foo 的数量:

# => Foo = 6
于 2014-05-09T09:23:55.427 回答
1

默认情况下,YourApplicationNameHere::Application.autoload_paths[]. 我(纯粹出于组织原因)app/models也为我的目录添加了一个 glob 。

config.autoload_paths += Dir["#{Rails.root}/app/models/**/"]
config.autoload_paths += Dir["#{config.root}/lib"]

通过此设置,我可以毫无困难地完成您在问题中提出的问题。这也应该使您受益,告诉 Rails 如果无法Userlib/模块的实例化中找到模型,该去哪里查找。

编辑

在您的问题中指定确切的错误消息也会有所帮助。

uninitialized constant Foo::User

User表示 Ruby/Rails 在命名空间内寻找Foo。前缀Userwith::强制查找全局命名空间。

module Foo
  LONG_EMAIL_ADDRESS = "foo@bar.com".rjust(::User::MAX_EMAIL_ADDRESS_LENGTH, "a")
end
于 2012-07-24T14:13:06.820 回答
1

看来您的类 User 尚未实例化,这似乎很不寻常,除非您在“模型”以外的位置有“user.rb”。通常情况下,类不会在开发中加载,除非它们专门在该目录中,但我使用的一种解决方案是这一行,您可以将其放在您希望在您拥有的违规行之前调用的代码中..

Rails.application.eager_load! if Rails.env == "development"

条件部分可能是不必要的,但我包括它只是为了确定它的效果只发生在开发中。

于 2012-07-24T14:19:02.220 回答