首页 > 解决方案 > Ruby 用守卫替换 if 块

问题描述

我有一个服务对象,它从分配的数据创建 CSV 文件。调用方法很简单:

  def initialize(data)
    @data = data
  end

  def call
    CSV.generate(headers: true, col_sep: ';') do |csv|
      csv << csv_headers

      data.uniq.each do |contract|
        next if contract.transient

        payment_details = [
          next_payment_date(contract),
          I18n.t("contracts.interval_options.#{contract.recurring_transaction_interval&.name}"),
        ]
        csv << payment_details
      end
    end
  end

  private

  def next_payment_date(contract)
    if contract.upcoming_installment.nil?
      I18n.t('tables.headers.no_next_payment_date')
    else
      contract.upcoming_installment.transaction_date.to_s
    end
  end

它运作良好,但我不认为next_payment_date如果阻塞真的很花哨,我想知道是否可以用一些警卫代替它?

由于 rubocop 我不能使用:

contract.upcoming_installment.nil? ? I18n.t('tables.headers.no_next_payment_date') : contract.upcoming_installment.transaction_date.to_s

标签: ruby-on-railsruby

解决方案


在我看来,该方法看起来不错。具有更好的可读性是增加 LOC 或引入方法的有利权衡。也就是说,如果你真的喜欢的话,有一些方法可以让它成为一个班轮。

contract.upcoming_installment&.transaction_date || I18n.t('tables.headers.no_next_payment_date')

&.如果是nilupcoming_installment应该回退到I18n.


推荐阅读