这种方法如何超出Rubocop帐户分支条件大小?

时间:2018-12-05 17:11:05

标签: ruby-on-rails rubocop

我有一个简单的before_save方法,用于根据模型中是否已经存在account_iduser_idapplication_id来分配contact_id

class Note < ApplicationRecord
  belongs_to :contact
  belongs_to :application
  belongs_to :user
  belongs_to :account

  before_save :assign_account_id

  private

  def assign_account_id
    self.account_id =
      if user_id.present?
        user.account.id
      elsif application_id.present?
        application.account.id
      elsif contact_id.present?
        contact.account.id
      end
  end
end

该方法有效,我认为该方法很简单,但是Rubocop坚持认为它略高于“分配分支条件”大小(ABC大小),该限制为 15 ,而我方法的ABC为 15.33

根据this article,ABC大小为15是通过8个分配,8个分支和8个条件实现的。但是,我只计算1个赋值self.account_id =,1个分支(返回)和3个条件(3个if / elsif语句)。

我误会了吗?其他任务,分支或条件从何而来?遍历模型层次结构的对present?的调用?

注意::我注意到正在寻找其他实现方式,我有兴趣了解导致该得分的原因。


对于任何感兴趣的人,这是我最终采用的满足ABC大小的解决方案。

self.account_id = [
  user&.account&.id,
  application&.account&.id,
  contact&.account&.id
].find(&:present?)

之所以选择它,是因为垂直列表最能传达字段的级联性质。我觉得我将能够返回到这一点,并且仍然能够了解它在做什么。

1 个答案:

答案 0 :(得分:4)

This is the web pagerubocop文档中的Metrics/AbcSize文档references in its source code(最新版本; 0.61.0)。

换句话说,它是:

  

标量ABC大小值(或“合计大小”)计算如下:   |ABC| = sqrt((A*A)+(B*B)+(C*C))

其中 A 分配的数量, B 分支 C的数量条件的数量。

  • 您的代码具有 1个分配self.account_id =)。
  • 您的代码具有 15个分支(!!!)(user_id.present?user.account.idapplication_id.present?application.account.idcontact_id.present?contact,{ {1}}和.account
  • 您的代码具有 3个条件.id)。

将其放在上面的公式中将得出:

if ... elsif ... elsif

这就是ABC = sqrt(1*1 + 15*15 + 3*3) = sqrt(235) = 15.32970... (四舍五入)值的来源。


我知道您并没有真正要求替代的实现,但是无论如何,这是一个

15.33

...甚至您可以考虑将这些括号移到单独的方法中。