我在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
由于未找到类User而失败。如何在lib上的该文件之前加载用户?
我正在我的application.rb中加载该文件:
config.autoload_paths += %W(#{config.root}/lib)
答案 0 :(得分:2)
第一部分是正确的:
config.autoload_paths += %W(#{config.root}/lib)
接下来,重要的是模块
module Foo
...
end
必须放入
lib/foo.rb
文件。
然后,它可以include
进入应用程序代码。
class Comment < ActiveRecord::Base
include Foo
...
end
如果不打算包含lib目录中的文件foo.rb
(但这可能是一种错误的方式),那么在这段代码中使用Rails模型和其他东西你应该把它放到foo.rb中:< / p>
require_relative "../config/environment.rb"
答案 1 :(得分:2)
解决方案是,我的/ lib文件实际上是rake文件所需要的,并且在Rails设置整个自动加载系统之前似乎加载了rake文件,因此无法找到模型。从.rake文件中删除require后,一切都开始工作了。
答案 2 :(得分:2)
我知道这是一个老问题,但我遇到了同样的问题,经过一些搜索,我找到了一个解决方案,所以我认为值得分享。
我想使用一个模型&#34; Foo&#34;位于my / lib目录中的一个必需文件中。首先,我这样做了,它没有工作:
# 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
答案 3 :(得分:1)
默认情况下,YourApplicationNameHere::Application.autoload_paths
为[]
。我(纯粹出于组织原因)也为我的app/models
目录添加了一个glob。
config.autoload_paths += Dir["#{Rails.root}/app/models/**/"]
config.autoload_paths += Dir["#{config.root}/lib"]
通过这种设置,我可以毫无困难地完成您在课题中提出的问题。这对您也有好处,告诉Rails在User
模块的实例化中找不到lib/
模型的位置。
修改强>
在您的问题中指定确切的错误消息也会有所帮助。
uninitialized constant Foo::User
表示Ruby / Rails正在User
命名空间中查找Foo
。使用User
前缀::
以强制查找全局命名空间。
module Foo
LONG_EMAIL_ADDRESS = "foo@bar.com".rjust(::User::MAX_EMAIL_ADDRESS_LENGTH, "a")
end
答案 4 :(得分:1)
看起来你的类User没有被实例化,这看起来很不寻常,除非你在'models'以外的位置有'user.rb'。通常情况下,类不会在开发中加载,除非它们专门位于该目录中,但我使用的一个解决方案是,您可以将此行放在您希望在违规行之前调用的代码中..
Rails.application.eager_load! if Rails.env == "development"
条件部分可能是不必要的,但我只是为了确定它的效果只发生在开发中。