我在控制器中有一些行为,我将其提取到模块中以便更好地进行测试,并在几个地方重复使用。关于此事有两个问题:
- 哪里是放置我的模块的好地方?它们需要被运行才能在控制器中使用,所以我考虑将它们放在
config/initializers/
目录下。但这似乎有点可疑。应该放在lib/
目录下吗? - 如何确保代码被运行,以使模块可以作为
include
添加到我的控制器中?
谢谢您。
我在控制器中有一些行为,我将其提取到模块中以便更好地进行测试,并在几个地方重复使用。关于此事有两个问题:
config/initializers/
目录下。但这似乎有点可疑。应该放在 lib/
目录下吗?include
添加到我的控制器中?谢谢您。
lib/
是一个非常好的模块存放位置,比起 config/initializers/
来说要好得多,至少在我看来是这样。如果有多个模块或者一个较大的模块,你也可以考虑将它作为插件放置在 vendor/plugins
中。
如果你将其放置在 lib/
中,你需要手动 require
这个文件。Rails 默认不会自动加载 lib/
目录下的文件。你可以将 require 放置在其中一个配置文件中。
我通常会将我的附加 autoloads(自动加载)放在 config/application.rb
中。下面的代码应该能解决问题(假设你的 .rb
文件位于一个名为 lib/my_module
的目录中):
config.autoload_paths += Dir["#{Rails.root}/lib/my_module"]
您必须确保您的模块是实际的module
而不是class
。然后,您可以简单地包含它:
# lib/my_module/foobar.rb
module Foobar
def foobar
"Hello world!"
end
end
# app/models/my_model.rb
class MyModel < ActiveRecord::Base
include Foobar
end
# rails console
>> obj = MyModel.first
=> #<MyModel id: 1, ...>
>> obj.id
=> 1
>> obj.foobar
=> "Hello world!"
class Application < Rails::Application
# require class extentions right now
Dir[Rails.root.join('app', 'extentions', "*.rb")].each {|l| require l }
# Custom directories with classes and modules you want to be autoloadable.
config.autoload_paths += Dir[Rails.root.join('app', 'mixins', '{**}')]
config.autoload_paths += Dir[Rails.root.join('app', 'services', '{**}')]
(我正在使用Rails 3)
尝试将控制器特定的模块放在app/controllers
中。不需要require
。
app/controllers
中。这样做会使目录结构失去意义。 - Jamison Dance