Rails - 模型辅助方法应该放在哪里?

4

出于代码规范的原因,我希望从主要的模型方法中隐藏某些实现细节。我不想让我的模型包含大量臃肿的方法,只需要保留最清晰和详细的功能。

例如:

class SomeModel
  #included stuff
  #fields & attrs

  def modelMethod
      variable = functionality1(functionality2)
      if some condition
        functionality3
      else
        functionality4
      end
  end

我应该把我的功能方法放在同一模型文件的privateprotected部分底部,还是应该将它们放入辅助文件中?如果我没错的话,帮助程序中的代码仅用于视图。这方面的惯例是什么?

这真的取决于您的需求。我鼓励您创建可重用的代码,考虑您需要的代码并查看是否可以提取它以便在其他地方使用,如果可以,则创建一个类并在使用它的任何地方创建该类的实例。我不喜欢模块的原因是它只是一种组织方法的方式,但最终您的类将以与它们在同一类/文件中具有相同数量的代码行数的方式结束。 - fanta
2个回答

6

拥有 privateprotected 与你要进行的清理类型无关。

这与继承方法的可见性/访问权限有关(尽管继承显然可用于重用)。

方法将取决于可重用性。为什么不利用关注点?假设我们有一个 SomeModel,希望多个模型实现暂停。

# app/models/some_model.rb
class SomeModel
  include Suspendable
end

然后添加您的模型关注点。
# app/models/concerns/suspendable.rb
module Suspendable
  extend ActiveSupport::Concern

  included do
    has_one :suspension
    scope :active, -> { joins('LEFT OUTER JOIN suspensions').where(suspension: {id: nil} }
  end
end

如果只适用于单个模型,但希望将模型严格保持为数据库操作(而非业务操作),则可以使用命名空间关注点。
# app/models/concerns/some_model/availability.rb
module SomeModel::Availability
  extend ActiveSupport::Concern

  module ClassMethods
    def availabilities_by_some_logic
    end
  end
end

http://api.rubyonrails.org/v5.0/classes/ActiveSupport/Concern.html


对我来说,很难确定什么是严格的业务逻辑和严格的数据库操作。我只想减少函数的大小(从20-100行到7-8行),并将不同的东西组织在其他地方,因为我并不一定对每个算法实现都感兴趣。 - MattSom
2
我知道你的意思。在“可暂停”示例中,我们将数据库操作和业务逻辑捆绑到可共享的功能中。我认为这不是严格的一种或另一种(很混乱,对吧?),而是功能分割。如果它永远不能被共享,那么可能要将其命名空间化到该模型。例如,app/models/product.rb 可能会获得 app/models/concerns/product/payable.rb。虽然可以说 payable.rb 在未来的版本中可能会被共享。 - fbelanger
我应该说 include SomeModel::ClassMethods 来将其包含到一个模型中吗? ::Availability 是必须的吗?它在这里有什么作用? - MattSom
你只需要包含 SomeModel::Availabiltiy,而不需要显式地包含它的 ClassMethods - fbelanger

1
如果您有一种或一组在各种模型中使用的方法: Rails Concerns 这与private/protected不同,您可以在Concern中拥有private/protected方法。这只是提取重复内容的方法。
如果您有一个模型需要的方法,仅限于该模型(而不是模型的子类,并且从未在类外调用): private 如果您有一个模型及其子类需要但不从模型外部调用的方法: protected
如果您需要能够从类外调用该方法: neither this answer更详细地介绍了这些内容。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接