27

我的控制器中有一些行为,我将其提取到一个模块中,以便更好地测试并在几个地方重新使用它。关于这个的两个问题:

  1. 哪里是放置我的模块的好地方?它们需要运行才能对控制器可用,所以我在考虑config/initializers/目录。不过,这对我来说似乎有点可疑。lib/?
  2. 如何确保代码运行,以便模块include在我的控制器中可用?

谢谢好心的先生们。

4

3 回答 3

38
  1. lib/是模块的好地方;config/initializers/比——至少在我看来要好得多。如果是几个模块,或者一个大模块,你也可以考虑把它做成一个插件,放在vendor/plugins.

  2. 如果你把它放进去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!"
于 2010-10-16T13:03:05.093 回答
1

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', '{**}')]

(我正在使用导轨 3)

于 2012-08-14T07:45:43.650 回答
-1

尝试将控制器特定模块放入app/controllers. 不需要require

于 2011-09-23T10:31:32.303 回答