1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Rails予約システム】時間枠の重複を防ぐバリデーションを実装した話(コピペOK)

Last updated at Posted at 2025-07-04

こんにちは、miyoshiです。
モニター開発も順調に進んでおります。
今回は、ISSUE6 のところで、実装できた部分と、取り入れてみたことを紹介していきます。

この記事も、前回公開した記事の続編です。

🎯 実現したいこと

✅ 管理者が「10:00〜11:00」の枠を登録済みのとき
→ もう一度「10:30〜11:30」など重なった時間枠を登録しようとしたら
🚫 エラーで登録できないようにする!

📦 モデル:Slotとは?

まず、今回の対象となる Slot モデルはこちら👇

rails g model Slot start_time:datetime end_time:datetime
rails db:migrate

施術する時間枠をslotと定義しました。

🛡️ 重複を防ぐバリデーション(コピペOK)

以下のコードを app/models/slot.rb に貼り付ければOK!

class Slot < ApplicationRecord
  validates :start_time, :end_time, presence: true
  validate :end_time_after_start_time
  validate :no_overlap

  private

  # ✅ 終了時間が開始時間より後であること
  def end_time_after_start_time
    return unless start_time.present? && end_time.present?

    if end_time <= start_time
      errors.add(:end_time, "は開始時刻より後にしてください")
    end
  end

  # 🚫 他の時間枠と重複していないかチェック
  def no_overlap
    return unless start_time.present? && end_time.present?

    overlapping_slots = Slot.where.not(id: id)
                            .where("start_time < ? AND end_time > ?", end_time, start_time)

    if overlapping_slots.exists?
      errors.add(:base, "この時間帯は他の時間枠と重複しています")
    end
  end
end

🔑 この記事のKEYコード

no_overlap メソッド

💬 この no_overlap メソッドは、Railsに用意されているわけではありません。自分で定義したオリジナルです!

class Slot < ApplicationRecord
  # ↓(これがないと動かない!その処理を実際に「呼び出す」指示)
  validate :no_overlap
 # ↓ 他の時間枠と重複していないかチェック
 def no_overlap
   return unless start_time.present? && end_time.present?

   overlapping_slots = Slot.where.not(id: id)
                          .where("start_time < ? AND end_time > ?", end_time, start_time)

  if overlapping_slots.exists?
    errors.add(:base, "この時間帯は他の時間枠と重複しています")
  end
end

🧠 なぜこれがKEYか?

  • Slot.where.not(id: id):自分自身(編集中のレコード)を除外
  • start_time < ? AND end_time > ?:部分的でも重なっている時間枠を検出
  • errors.add(:base, "..."):重複がある場合にエラーメッセージを表示して登録をブロック

このコードこそが、
「同じ時間帯に複数登録できてしまう問題をRails側で防ぐ」
ための決定打です💥

📚 モニター開発中!!

🧑‍💻 Railsで予約システム「sorairo note」開発中!
開発途中での学び、失敗などを発信中🌈
→ 他の機能も記事で公開してます!

🙌 最後まで読んでくれてありがとう!

この記事が「時間かぶっちゃう問題😇」の解決に役立てば嬉しいです!

🌟 LGTM やシェアしてもらえると励みになります!

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?