ruby-on-rails - 此方法如何超过 Rubocop 帐户分支条件大小?

标签 ruby-on-rails rubocop

我有一个简单的 before_save 方法,用于根据 user_idapplication_idcontact_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 个 if/elsif 语句)。

我错了吗?额外的任务、分支或条件从何而来?对 present? 的调用,遍历模型层次结构?

注意:我注意到正在寻找替代实现,我有兴趣了解导致此分数的原因。


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

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

我选择它是因为垂直列表最能传达字段的级联特性。我觉得我可以回到这里,并且仍然能够理解它在做什么。

最佳答案

This is the web page rubocop 文档 references in its source code ,在 Metrics/AbcSize 的文档中(截至最新版本;0.61.0)。

换句话说,它说:

A scalar ABC size value (or "aggregate magnitude") is computed as: |ABC| = sqrt((A*A)+(B*B)+(C*C))

其中AAssignments的数量,BBranchesC的数量条件的数量。

  • 您的代码有 1 个分配 (self.account_id =)。
  • 您的代码有 15 个分支 (!!!) (user_id, .present?, user, .account, .id, application_id, .present?, application, .account, .id, contact_id, .present?, contact, .account.id)
  • 您的代码有 3 个条件(if ... elsif ... elsif)。

将其代入上述公式得到:

ABC = sqrt(1*1 + 15*15 + 3*3)
    = sqrt(235)
    = 15.32970...

这就是 15.33 的(四舍五入)值的来源。


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

def assign_account_id
  self.account_id = (user || application || contact).account.id
end

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

关于ruby-on-rails - 此方法如何超过 Rubocop 帐户分支条件大小?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53637433/

相关文章:

ruby-on-rails - rails 3 : What happens after a form button is pressed?

ruby-on-rails - 如何从自定义类访问 'request' 对象(或类似对象)?

ruby - 用一个期望测试自定义异常?

ruby-on-rails - 如何在不同时区显示 Rails 表单日期时间选择?

mysql - Rails 如何构建 MySQL 语句?

ruby-on-rails - 在 Ruby 中重新实现 Enumerable Map 方法

ruby-on-rails - rubocop 警察不同意 : Layout/EmptyLineAfterGuardClause vs Layout/TrailingWhitespace

ruby-on-rails - 启用 rails 的 Rubocop 和 Style/IndentationConsistency

ruby-on-rails - 是否有专门针对 rails 5.2.3 的 Rubocop 配置?