【问题标题】:How to refactor "shared" methods?如何重构“共享”方法?
【发布时间】:2012-09-10 21:55:11
【问题描述】:

我正在使用 Ruby on Rails 3.2.2,我想从我的模型/类中“提取”一些方法。也就是说,在不止一个类/模型中,我有一些方法(注意:方法与用户授权相关,并被命名为“CRUD方式”),它们实际上是相同的;所以我认为DRY 的方法是将这些方法放在“共享”模块或类似的东西中。

实现此目的的常见且正确的方法是什么?例如,我应该将“共享”代码放在哪里(在哪些目录和文件中)?如何在我的类/模型中包含提到的方法?你有什么建议?

注意:我正在寻找“Ruby on Rails 的制作方法”。

【问题讨论】:

    标签: ruby-on-rails ruby ruby-on-rails-3 methods refactoring


    【解决方案1】:

    一种流行的方法是使用 ActiveSupport 关注点。然后,您通常会将通用逻辑放在 app/concerns/app/models/concerns/ 目录下(根据您的偏好)。一个说明性的例子:

    # app/concerns/mooable.rb
    module Mooable
      extend ActiveSupport::Concern
    
      included do
        before_create :say_moo
    
        self.mooables
          where(can_moo: true)
        end
      end
    
      private
    
      def say_moo
        puts "Moo!"
      end
    end
    

    在模型中:

    # app/models/cow.rb
    class Cow < ActiveRecord::Base
      include Mooable
    end
    

    为了使其以这种方式工作,您必须将以下行添加到 config/application.rb

    config.autoload_paths += %W(#{config.root}/app/concerns)
    

    更多信息:

    【讨论】:

    • 将模块添加到lib目录呢?
    • 注意:上一条评论中的问题是由于 config.autoload_paths += %W(#{config.root}/app/concerns) 的沉迷:在我的情况下,这种方法是一种“制作东西的好方法”吗?
    • @user12882 是的,可以通过类似的方式完成。 config.autoload_paths += %W(#{config.root}/lib)config.autoload_paths += %W(#{config.root}/lib/concerns)
    • 对不起,如果我可以“坚持”/“重复自己”,但最常用的方法是什么(libapp/concerns 目录)?
    • @user12882 我相信app/concerns源自这里:weblog.jamisbuck.org/2007/1/17/concerns-in-activerecord我们已经在我们的项目中使用了它。这个有用的要点提到了 app/models/concernsapp/controllers/concerns- 可能是你想要 DRY 控制器的好主意:gist.github.com/1014971 最后这一切都取决于你:)。
    【解决方案2】:

    我的回答与 RoR 没有直接关系,而与 Ruby 有更多关系。

    在 Ruby 中可以通过多种方式共享通用代码。在我看来,最明显的方法是创建包含代码的 Ruby 模块,然后将它们包含在您的类/模型中。这些共享模块通常位于应用根目录的 lib 目录下。例如:

    # lib/authorizable.rb
    
    module Authorizable
      def method1
         #some logic here
      end
    
      def method2
         #some more logic here
      end
    end
    
    # app/models/user.rb
    
     class User < ActiveRecord::Base
        include Authorizable
     end
    

    User 类现在可以调用属于 Authorizable 模块的 method1 和 method2。您可以将此模块包含在您想要的任何其他 Ruby 类中,这样您就可以干燥您的代码。

    【讨论】:

    • 我可能会指出 ActiveSupport::Concern,这是 Rails 中用于此目的的常用实用程序类。
    • 您的代码有效,但我正在寻找一种更“Ruby on Railities”的方式来制作@numbers1311407 所说的东西。
    • 那么我建议您在问题中提及它。这样,您将获得更接近您正在寻找的答案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-28
    • 1970-01-01
    • 2011-12-25
    • 1970-01-01
    • 2013-08-31
    • 1970-01-01
    相关资源
    最近更新 更多