从Rails 3项目中的lib目录中访问模型

时间:2012-07-24 13:36:49

标签: ruby-on-rails

我在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)

5 个答案:

答案 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"

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