Tech Racho エンジニアの「?」を「!」に。
  • Ruby / Rails関連

Railsの技: 日付同士をbefore?とafter?で比較する(翻訳)

概要

原著者の許諾を得て翻訳・公開いたします。

日本語タイトルは内容に即したものにしました。

Railsの技: 日付同士をbefore?とafter?で比較する(翻訳)

私は日付同士を比較するコードを書くときに、わけもなく緊張してしまいます。気をつけていないと<>=の向きを取り違えて逆に書いてしまいがちなのです。

私は日付の比較を「より前(before)」か「より後(after)」で考えるので、たとえばstart_dateend_date「より大きい(greater than)か」あるいは「より小さい(less than)か」という発想に置き換えようとすると混乱してしまいます。

使い方

ありがたいことに、私が二度とこのような失敗をしないように、Railsはすべての日付関連の比較にbefore?メソッドとafter?メソッドを追加してくれています。おかげさまで私のような者にとっては助かります。

start_date = Date.new(2019, 3, 31)
end_date = Date.new(2019, 4, 1)

start_date.before? end_date
#=> true
end_date.after? start_date
#=> true

start_date = Date.new(2020, 8, 11)
end_date = Date.new(2018, 8, 11)

start_date.before? end_date
#=> false

気がつくと私は、以下のようにRailsのモデルで日付同士が有効範囲に収まっているかどうかをバリデーションするときにbefore?after?を愛用するようになりました。

class Promotion < ApplicationRecord
  validate :valid_eligiblity_range?

  def valid_eligiblity_range?
    return unless expiration_date? && start_date?

    if !expiration_date.after?(start_date)
      errors.add(:start_date, "must be before Expiration Date")
      errors.add(:expiration_date, "must be after Start Date")
    end
  end
end

参考資料

関連記事

Railsの技: 起動時に環境変数の存在を確認する(翻訳)


CONTACT

TechRachoでは、パートナーシップをご検討いただける方からの
ご連絡をお待ちしております。ぜひお気軽にご意見・ご相談ください。