こんにちは、miyoshiです。
モニター開発も順調に進んでおります。
今回は、ISSUE6 のところで、実装できた部分と、取り入れてみたことを紹介していきます。
この記事も、前回公開した記事の続編です。
- 「モニター開発」で進めたら、いい感じの話
- 【Rails × Devise】初心者エンジニアがユーザー認証を実装してみた話
- Rails × Devise × Basic認証】管理画面のセキュリティと使いやすさを両立した話
- Rails】初心者エンジニアが削除ボタンが動かない話!!原因はJavaScriptの・・
- 【Rails × 管理画面】namespaceで管理者用施術メニュー管理機能を実装してみた話
🎯 実現したいこと
✅ 管理者が「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 やシェアしてもらえると励みになります!