在Rails中将目录添加到加载路径?

pjb*_*jb3 64 ruby ruby-on-rails

从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
Run Code Online (Sandbox Code Playgroud)

add_to_load_path是我正在寻找的方法.

Jam*_*oms 108

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

该代码目前已被注释为:

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

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

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

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

config.autoload_paths += %W(#{config.root}/app/validators)
Run Code Online (Sandbox Code Playgroud)

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岁的结果可以回答你的问题并尽快结束你的任务,那不是很好吗? (81认同)
  • @Bassetassen - StackOverflow旨在成为始终相关且适用的问答的存储库.当事情发生变化(即版本更新)时,应该适当更新答案或给出新的答案.口袋里满是四分卫做对了. (24认同)
  • 为了记录,我很高兴发布了这个回复.接受的答案不再正确. (14认同)
  • 如果目录在`app /`下,你不需要在任何地方添加它,它应该只是默认工作(绝对在3.2.12).Rails有`eager_load_paths`,在开发过程中充当autoload_paths,在生产中充满热情.所有`app/*`目录都会自动添加到那里. (7认同)
  • 对于任何想知道的人,@ hakunin的评论仍然适用于Rails 4.在`app/*`中添加的任何目录都可以. (3认同)
  • 感谢您抽出宝贵时间回答这个老问题 - 你绝对节省了我的时间.我讨厌这个网站上有多少人认为它应该以他们认为应该的方式工作. (2认同)

rya*_*anb 60

对于旧版本的Rails:

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

config.load_paths << "#{RAILS_ROOT}/app/widgets"
Run Code Online (Sandbox Code Playgroud)

-

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

  • ActiveSupport :: Dependencies.autoload_paths <<"#{RAILS_ROOT}/app/widgets" (9认同)

Jac*_*cob 27

在Rails 3中,您可以在config/application.rb中设置它,默认情况下提供此示例:

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

  • #config.autoload_paths + =%W(#{config.root}/extras) (13认同)

Pet*_*per 21

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

因此,新的工作流程是:

  1. 在/ app目录中创建一个新文件夹和类
  2. spring stop在命令行上运行
  3. bin/rails r 'puts ActiveSupport::Dependencies.autoload_paths'在命令行上检查autoload-paths .现在应该列出新文件夹.
  4. spring start在命令行上运行


Tia*_*nco 10

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

# Add the widgets folder to the autoload path
Rails.application.configure do
  config.autoload_paths << "#{Rails.root}/app/widgets"
end
Run Code Online (Sandbox Code Playgroud)

  • Rails 5实际上自动加载了app目录中的所有文件夹. (6认同)

gda*_*ram 8

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

代替:

ActiveSupport::Dependencies.load_paths << "#{RAILS_ROOT}/app/widgets"
Run Code Online (Sandbox Code Playgroud)

您可能需要这样做:

ActiveSupport::Dependencies.autoload_paths << "#{RAILS_ROOT}/app/widgets"
Run Code Online (Sandbox Code Playgroud)

  • Rails.root在Rails 3中是必需的,而不是RAILS_ROOT (2认同)