此方法如何超过 Rubocop 帐户分支条件大小?
How is this method exceeding the Rubocop Account Branch Condition size?
我有一个简单的 before_save
方法,用于根据 user_id
、application_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 个分支(return)和三个条件(3 个 if/elsif 语句)。
我错了吗?额外的任务、分支或条件从何而来?对 present?
的调用,遍历模型层次结构?
注意:我注意到正在寻找替代实现,我有兴趣了解导致此分数的原因。
对于任何感兴趣的人,这是我最终采用的满足 ABC 大小的解决方案。
self.account_id = [
user&.account&.id,
application&.account&.id,
contact&.account&.id
].find(&:present?)
之所以选择它,是因为垂直列表最能传达字段的级联特性。我觉得我能够 return 做到这一点并且仍然能够理解它在做什么。
This is the web page that the rubocop
documentation 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))
其中A是Assignments的个数,B是[=的个数50=]Branches和C是Conditions.
的个数
- 您的代码有 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
...您甚至可以考虑将这些括号移动到一个单独的方法中。
我有一个简单的 before_save
方法,用于根据 user_id
、application_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 个分支(return)和三个条件(3 个 if/elsif 语句)。
我错了吗?额外的任务、分支或条件从何而来?对 present?
的调用,遍历模型层次结构?
注意:我注意到正在寻找替代实现,我有兴趣了解导致此分数的原因。
对于任何感兴趣的人,这是我最终采用的满足 ABC 大小的解决方案。
self.account_id = [
user&.account&.id,
application&.account&.id,
contact&.account&.id
].find(&:present?)
之所以选择它,是因为垂直列表最能传达字段的级联特性。我觉得我能够 return 做到这一点并且仍然能够理解它在做什么。
This is the web page that the rubocop
documentation 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))
其中A是Assignments的个数,B是[=的个数50=]Branches和C是Conditions.
的个数- 您的代码有 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
...您甚至可以考虑将这些括号移动到一个单独的方法中。