#ruby-on-rails #ruby #code-climate
#ruby-on-rails #ruby #код-климат
Вопрос:
У меня есть приложение, которое подключено к CodeClimate, и оно показывает мне ошибку Method upstream_transactions has a Cognitive Complexity of 6 (exceeds 5 allowed)
с указанным ниже кодом:
def upstream_transactions(bank_account:, external_account:, external_transactions:)
external_transactions.each do |transaction|
next if transaction.currency != 'USD'
transfer = BankTransfer.unscoped.find_or_create_by(
Эта ошибка появилась после того, как я добавил строку next if transaction.currency != 'USD'
.
def upstream_transactions(bank_account:, external_account:, external_transactions:)
external_transactions.each do |transaction|
next if transaction.currency != 'USD'
transfer = BankTransfer.unscoped.find_or_create_by(
customer_id: customer.id, transaction_identifier: transaction.transaction_id
)
next if transfer.deleted_at?
transfer.update(
date: transaction.booked_at,
# (...) some other params
)
end
Success(bank_account: bank_account, external_account: external_account)
end
Как избежать такой ошибки?
Ответ №1:
Вы могли бы уменьшить сложность, создав несколько вспомогательных методов, которые вы можете вызвать. Может быть
def obtain_transfer(transaction)
BankTransfer.unscoped.find_or_create_by(
customer_id: customer.id, transaction_identifier: transaction.transaction_id)
end
В
next unless transaction.currency == 'USD'
хотя вы могли бы даже
external_transactions.select { |t| t.currency == 'USD' }.each do |transaction|
Следует ли вызывать метод upstream_USD_transactions
вместо этого? Было бы разумно, чтобы потенциальный абонент каким-то образом знал, что он собирается отменить все переводы, не связанные с долларами США?
Ответ №2:
Это не ошибка, когнитивная сложность — это:
мера того, насколько сложно интуитивно понять единицу кода
Итак, когда вы добавили этот дополнительный оператор управления потоком next if transaction.currency != 'USD'
, это усложнило тестирование кода. Добавление операторов типа if
, unless
, amp;amp;
, и всего, что добавляет дополнительное управление логическим потоком (например, операторы переключения), увеличит сложность.
Вы можете использовать два подхода, чтобы попытаться минимизировать эту сложность:
- Измените добавленный оператор
- Измените существующий метод
Если в уже сложный метод был добавлен небольшой оператор, попробуйте взглянуть на то, что можно упростить в этом существующем методе. Подобно тому, что @nullTerminator предложил в своем ответе, разделение логики на различные вспомогательные методы может снизить сложность. Меньшие методы было бы легче тестировать, и каждый из них должен иметь меньшую когнитивную сложность.