はじめに
Railsアプリケーション開発において、DRY(Don't Repeat Yourself)原則を守ることは非常に重要です。同じコードを繰り返し書くことは保守性や拡張性の低下を招くため、共通の機能はモジュール化して再利用することが望まれます。本記事では、異なるコントローラで使用される「時間スロットの生成」ロジックをモジュールとして抽出し、どのように再利用するかを説明します。
問題の定義
例として、スケジュール管理機能を持つアプリケーションを考えます。予約システムやスタッフのスケジュール管理システムでは、特定の日に対する利用可能な時間スロットを生成する必要があります。このロジックが複数のコントローラで必要とされる場合、コードの重複を避けるためにモジュールとして抽出することが理想的です。
時間スロット生成ロジックのモジュール化
まず、TimeSlotGenerator
という名前のモジュールを作成し、共通の時間スロット生成メソッドを定義します。
モジュールの作成
# app/controllers/concerns/time_slot_generator.rb
module TimeSlotGenerator
extend ActiveSupport::Concern
def generate_time_slots(company)
selected_date = params[:date].present? ? Date.parse(params[:date]) : Date.today
day_of_week = selected_date.wday # 曜日を取得
company_business_days = company.company_business_days.joins(:business_day).where(business_days: { day_of_week: day_of_week })
company_business_hours = company_business_days.flat_map(&:company_business_hours)
# 最も早い開始時間と最も遅い終了時間を見つけるか、デフォルト値を使用する
start_time = company_business_hours.min_by(&:start_time)&.start_time || Time.zone.parse("09:00")
end_time = company_business_hours.max_by(&:end_time)&.end_time || Time.zone.parse("19:00")
time_slots = []
current_time = start_time
while current_time < end_time do
time_slots << current_time.strftime("%H:%M")
current_time += 15.minutes
end
time_slots
end
end
コントローラでのモジュールの使用
次に、このモジュールを必要とするコントローラでインクルードします。
# app/controllers/reservations_controller.rb
class ReservationsController < ApplicationController
include TimeSlotGenerator
...
end
まとめ
この方法により、時間スロットの生成ロジックを一箇所に集約し、複数のコントローラ間で簡単に共有できるようになりました。これによってコードの重複を減らし、保守性と拡張性を向上させることができます。モジュール化はRailsアプリケーションの設計において非常に有効な手法の一つです。