`this_week?` に `start_day` 引数を追加し、`all_week` との一貫性を確保
this_week? にオプショナルな start_day 引数が追加され、all_week・beginning_of_week・end_of_week と同じインターフェースに統一されました。これにより、グローバル設定を変更せずに呼び出し単位で週の開始曜日を指定できるようになります。
背景
this_week? は同ファミリーの他メソッドと異なり、グローバルな Date.beginning_of_week 設定にしか依存できませんでした。関連メソッドである all_week・beginning_of_week・end_of_week はいずれも start_day 引数を受け付けており、この非対称性が実用上の制約となっていました。
マルチテナントやi18n対応のアプリケーションでは、米国(:sunday 始まり)と欧州(:monday 始まり)のような異なるロケールを同一プロセスで扱う場面があります。こうした場合に around_action 等で Date.beginning_of_week= を切り替える方法は、並行環境での共有可変状態となりバグを生みやすくなります。また、「月曜始まりの今週」と「日曜始まりの今週」を並べて表示するレポートやダッシュボードでは、グローバル設定の一時的な変更なしにこれを実現する手段がありませんでした。
本変更はデフォルト値を Date.beginning_of_week のままとしており、引数を渡さない既存の呼び出しは挙動が変わらない完全な後方互換変更です。
技術的な変更
activesupport/lib/active_support/core_ext/date_and_time/calculations.rb の this_week? メソッドに start_day 引数が追加され、内部で呼び出す all_week にそのまま渡されるようになりました。
変更前:
# Returns true if the date/time falls within the current week.
def this_week?
::Date.current.all_week.include?(to_date)
end
変更後:
# Returns true if the date/time falls within the current week.
# Week is assumed to start on +start_day+, default is
# +Date.beginning_of_week+ or +config.beginning_of_week+ when set.
def this_week?(start_day = Date.beginning_of_week)
::Date.current.all_week(start_day).include?(to_date)
end
変更は2行のみのシンプルな差分です。引数を all_week へそのまま委譲する実装のため、all_week が対応している全ての曜日シンボル(:monday・:sunday 等)がそのまま利用できます。使用例は以下の通りです:
date.this_week? # Date.beginning_of_week をそのまま使用(変更なし)
date.this_week?(:sunday) # 日〜土の週で判定
date.this_week?(:monday) # 月〜日の週で判定
テストは activesupport/test/core_ext/date_time_ext_test.rb に test_this_week_with_start_day として追加されました。Date.current を 2000年1月5日(水曜日)にスタブし、デフォルト(月曜始まり:1/3〜1/9)と :sunday 指定(日曜始まり:1/2〜1/8)の境界値を各3ケースで網羅しています。
設計判断
既存メソッドの委譲パターンを踏襲する方式が採用されました。this_week? の内部実装はもともと all_week に依存しており、引数を追加してそのまま渡すだけで目的が達成できる構造になっていました。新たなロジックを導入せず、all_week の週範囲計算をそのまま再利用しているため、週の境界判定のロジックが一箇所に集約され続けます。
デフォルト値を Date.beginning_of_week(メソッド呼び出し時に評価されるデフォルト引数)としている点も、他のメソッドと完全に一致しています。これはクラスレベルの設定を動的に参照する既存の設計と整合しており、引数省略時の挙動が従来と変わらないことを保証します。
まとめ
本PRは、this_week? が同ファミリーの中で唯一欠いていた start_day の柔軟性を、わずか2行の実装変更で補完した変更です。グローバル状態に依存せずに週の開始曜日を呼び出し単位で指定できるようになったことで、マルチテナントやi18n対応アプリケーションにおけるスレッドセーフな日付判定が実現できます。