【发布时间】:2011-04-26 02:22:20
【问题描述】:
我的控制器中有一些行为,我将其提取到一个模块中,以便更好地测试并在几个地方重复使用它。关于这个的两个问题:
- 哪里是放置模块的好地方?它们需要运行才能对控制器可用,所以我在想
config/initializers/目录。不过,这对我来说似乎有点可疑。lib/? - 如何确保代码能够运行,以便控制器中的
include可以使用这些模块?
谢谢各位大佬。
【问题讨论】:
我的控制器中有一些行为,我将其提取到一个模块中,以便更好地测试并在几个地方重复使用它。关于这个的两个问题:
config/initializers/ 目录。不过,这对我来说似乎有点可疑。 lib/?include 可以使用这些模块?谢谢各位大佬。
【问题讨论】:
lib/ 是放置模块的好地方;比config/initializers/ 好得多——至少在我看来。如果是几个模块,或者一个大模块,也可以考虑做一个插件,放在vendor/plugins。
如果将其放入 lib/,则需要手动 require 文件。默认情况下,Rails 不会自动加载 lib/ 目录中的文件。您可以将要求放在您的配置文件之一中。
我通常将额外的自动加载放在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!"
【讨论】:
尝试将控制器特定模块放入app/controllers。不需要require。
【讨论】:
app/controllers。这违背了目录结构的目的。
1) 我喜欢说: 我在 app/extensions 下的类扩展 我在 /app/mixins 下的模块 我在 /app/services 下的服务
2) 您可以配置您的应用程序以在 config/application.rb 中加载所有这些: 应该以正确的方式要求类扩展 并且可以将 mixins 和服务添加到您的自动加载路径中
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)
【讨论】: