【问题标题】:Accessing models from within the lib directory in a Rails 3 project从 Rails 3 项目的 lib 目录中访问模型
【发布时间】:2014-05-09 17:23:55
【问题描述】:

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

【问题讨论】:

  • 如何在您的 Rails 应用程序中包含 lib?在 Rails 3 中,默认情况下它不会自动加载,因此显示您如何访问 lib/foo.rb 会很有帮助。
  • 你有这个模块吗?如果有,它包含在哪里?
  • @denis.peplin,不,我不需要,如果需要,我会收到找不到文件的错误。
  • 不需要,include 它。请看我的回答。

标签: ruby-on-rails


【解决方案1】:

第一部分做得对:

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

接下来,重要的是,模块

module Foo
  ...
end

必须放入

lib/foo.rb

文件。

然后,可以将included 转换为应用程序代码。

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

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

require_relative "../config/environment.rb"

【讨论】:

  • 我不是试图从模型中访问库,而是从库文件中访问模型。
  • 所以试试require_relative "../config/environment.rb"
【解决方案2】:

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

【讨论】:

    【解决方案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
    

    【讨论】:

      【解决方案4】:

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

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

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

      【讨论】:

        【解决方案5】:

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

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

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

        编辑

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

        uninitialized constant Foo::User
        

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

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

        【讨论】:

        • 这对我不起作用。我尝试了几种变体,但总是得到:未初始化的常量 Foo::User。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-08-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-12-03
        • 1970-01-01
        相关资源
        最近更新 更多