如何在Rails 3中的控制器中使用mixins或模块?

时间:2010-10-15 18:42:48

标签: ruby-on-rails-3 mixins

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

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

3 个答案:

答案 0 :(得分:38)

  1. lib/是模块的绝佳场所;比config/initializers/要好得多 - 至少在我看来。如果它是几个模块或一个大模块,您还可以考虑将其设置为插件并将其放在vendor/plugins中。

  2. 如果您将其放入lib/,则需要手动require该文件。默认情况下,Rails不会在lib/目录中自动加载文件。您可以将require放在一个配置文件中。

  3. 我通常会在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!"
    

答案 1 :(得分:1)

1)我喜欢说:    app / extentions下的课堂扩展    我的模块在/ 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)

答案 2 :(得分:-1)

尝试将控制器特定模块放在app/controllers中。不需要require