代码之家  ›  专栏  ›  技术社区  ›  Soviut

此方法如何超过rubocop帐户分支条件大小?

  •  3
  • Soviut  · 技术社区  · 6 年前

    我有一个简单的 before_save 用于分配 account_id 基于是否 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大小),其中限制是 十五 我的方法是ABC 十五点三三 .

    根据 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 回复  |  直到 6 年前
        1
  •  4
  •   Tom Lord    6 年前

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

    换言之,它说:

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

    在哪里? 作业 , 分支机构 C 条件 .

    • 您的代码已经 1赋值 ( self.account_id = )
    • 您的代码已经 15枝 (!!!!)( user_id , .present? , user , .account , .id , application_id , .现在? , application , .账户 , 身份证 , contact_id , .现在? , contact , 帐户 身份证 )
    • 您的代码已经 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
    

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

    推荐文章