Как этот метод превышает размер условия филиала Rubocop? - PullRequest
0 голосов
/ 05 декабря 2018

У меня есть простой 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

Метод работает и, на мой взгляд, примерно настолько прост, насколько я могу его получить, но Рубокоп настаивает, что он немного превышает размер Assign Branch Condition (размер ABC), где предел равен 15 и ABC моего методасоставляет 15,33 .

Согласно этой статье размер 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?)

Я выбрал его, потому что вертикальный список наиболее сильно передает каскадный характер полей,Я чувствовал, что смогу вернуться к этому и все еще суметь ухватиться за то, что он делает.

1 Ответ

0 голосов
/ 05 декабря 2018

Это веб-страница , на которую rubocop документация ссылается в исходном коде , в документации на Metrics/AbcSize (по состоянию на последнюю версию; 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, .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

... И вы могли бы даже подумать о переносе этих скобок в отдельный метод.

...