【问题标题】:Adding a directory to the load path in Rails?在 Rails 的加载路径中添加目录?
【发布时间】:2009-08-03 17:11:58
【问题描述】:

从 Rails 2.3 开始,将目录添加到加载路径以使其与 Rails 的自动重新加载机制挂钩的正确方法是什么?

我正在考虑的具体示例是我有一个类,它有几个使用 STI 的子类,我认为将它们放在子目录中而不是使顶层混乱是个好主意。所以我会有类似的东西:

#app/models/widget.rb
class Widget < ActiveRecord::Base
   add_to_load_path File.join(File.dirname(__FILE__), "widgets")
end

#app/models/widgets/bar_widget.rb
class BarWidget < Widget
end

#app/models/widgets/foo_widget.rb
class FooWidget < Widget
end

这是我正在寻找的 add_to_load_path 方法。

【问题讨论】:

    标签: ruby-on-rails ruby


    【解决方案1】:

    在当前版本的 Rails (3.2.8) 中,这已在 application.rb 文件中更改。

    代码目前注释为:

      # Custom directories with classes and modules you want to be autoloadable.
      # config.autoload_paths += %W(#{config.root}/extras)
    

    需要更新 autoload_paths 值。尝试修改以前的 load_paths 变量会导致此错误。

    /configuration.rb:85:in `method_missing': undefined method `load_paths' for #<Rails::Application::Configuration:0xac670b4> (NoMethodError)
    

    例如,对于要添加到 autoload_paths 配置的每个路径,添加类似于以下内容的行:

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

    config.autoload_paths 接受一个路径数组,Rails 将从这些路径中自动加载常量。 默认为app下的所有目录。

    http://guides.rubyonrails.org/configuring.html


    来自下面的评论员(hakunin):

    如果目录在app/ 下,你不需要在任何地方添加它,它应该默认工作(肯定在 3.2.12 中)。 Rails 有eager_load_paths,在开发中充当autoload_paths,在生产中充当急切负载。 所有app/* 目录都会自动添加到那里。

    【讨论】:

    • 兄弟,你知道谷歌搜索引擎,它总是列出 3 年前的搜索结果。如果 3 岁的结果可以回答您的问题并尽快结束您的任务,那不是很好吗?
    • @Bassetassen - StackOverflow 旨在成为始终相关且适用的问题和答案的存储库。当事情发生变化(即版本更新)时,应适当更新答案或给出新答案。口袋满满的四分之一做了正确的事。
    • 郑重声明,我很高兴发布了此回复。接受的答案不再正确。
    • 如果目录在app/下,你不需要在任何地方添加它,它应该默认工作(肯定在3.2.12中)。 Rails 有 eager_load_paths 在开发中充当 autoload_paths,在生产中充当预加载。所有app/* 目录都会自动添加到那里。
    • 对于任何想知道的人,@hakunin 的评论仍然适用于 Rails 4。在 app/* 中添加的任何目录都可以工作。
    【解决方案2】:

    对于旧版本的 Rails:

    您可以在 environment.rb 配置文件中执行此操作。

    config.load_paths << "#{RAILS_ROOT}/app/widgets"
    

    --

    对于 Rails 3,请参阅下面的答案

    【讨论】:

    • ActiveSupport::Dependencies.autoload_paths
    • 查看完全正确的答案。这个现在已经过时了。
    【解决方案3】:

    Rails 5 中,您不必再从应用目录中显式加载文件夹。放置在里面的所有文件夹都可以直接使用。您不必触摸任何配置文件。但似乎 Spring 存在一些问题。

    因此,新的工作流程是:

    1. 在 /app 目录中创建一个新文件夹和类
    2. 在命令行上运行spring stop
    3. 在命令行中使用bin/rails r 'puts ActiveSupport::Dependencies.autoload_paths' 检查自动加载路径。现在应该会列出新文件夹。
    4. 在命令行运行spring start

    【讨论】:

    • 我发现这个不可靠并且我从未安装过 spring 或在我的 gemfile 中(执行时)。不可靠是指 puts 代码找到了该目录,但其中没有任何文件被加载以包含在其他地方。当我将 autoload_path 放在 config/application.rb 中时,包括类确实对我有用。
    • @Mirv - 你使用的是哪个版本的 Rails?看看:guides.rubyonrails.org/…
    • 对我有用,谢谢。 spring server 对 2019 年正确,而不是 spring start
    • 哦春天...谢谢!你救了我。
    • 谢谢你,你节省了我的时间。
    【解决方案4】:

    在 Rails 3 中,您可以在 config/application.rb 中进行设置,默认提供此示例:

    # Add additional load paths for your own custom dirs
    # config.load_paths += %W( #{config.root}/extras )
    

    【讨论】:

    • # config.autoload_paths += %W(#{config.root}/extras)
    【解决方案5】:

    在 Rails 5 上,您需要将以下代码添加到 environment.rb:

    # Add the widgets folder to the autoload path
    Rails.application.configure do
      config.autoload_paths << "#{Rails.root}/app/widgets"
    end
    

    【讨论】:

    • Rails 5 实际上会自动加载应用目录中的所有文件夹。
    • 谢谢。这是我上次检查时的默认行为,但老实说,我不记得这是否是此处所述的仅生产问题:blog.bigbinary.com/2016/08/29/…
    【解决方案6】:

    rails 3 的另一个更新——activesupport 3.0.0:

    代替:

    ActiveSupport::Dependencies.load_paths << "#{RAILS_ROOT}/app/widgets"
    

    您可能需要这样做:

    ActiveSupport::Dependencies.autoload_paths << "#{RAILS_ROOT}/app/widgets"
    

    【讨论】:

    • Rails.root 在 Rails 3 中是必需的,而不是 RAILS_ROOT
    • 在 Rails 3.0.3 下,我不得不使用 ActiveSupport::Dependencies.autoload_paths += %W( #{Rails.root.to_s}/app/libs )
    【解决方案7】:

    我发现我需要在配置块之后执行此操作——不再访问配置对象。

    这成功了

    ActiveSupport::Dependencies.load_paths << "#{RAILS_ROOT}/app/widgets"
    

    【讨论】:

    • 不适用于 Rails 6,请参阅 ActiveSupport::Dependencies.methods 的方法
    【解决方案8】:

    config/application.rb 中添加config.autoload_paths &lt;&lt; "#{config.root}/models/widgets"

    文件应如下所示:

    module MyApp
      class Application < Rails::Application
        config.autoload_paths << "#{config.root}/models/widgets"
      end
    end
    

    我知道这适用于 Rails 4 和 5。可能也适用于其他版本。

    【讨论】:

      【解决方案9】:

      如果要添加多个目录:

      config.autoload_paths += Dir[Rails.root / "components/*/app/public"]
      

      (这是 packwerk 自动加载的示例)

      【讨论】:

      • 感谢 Dorian 这正是我需要做的(特别是对于 packwerk),我花了一个多小时试图让它工作!感谢分享
      猜你喜欢
      • 2011-11-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-12-17
      • 2018-08-03
      • 2022-01-18
      相关资源
      最近更新 更多