こんにちは、miyoshiです。
モニター開発も順調に進んでおります。
今回は、ISSUE5のところで、実装できた部分と、取り入れてみたことを紹介していきます。
この記事も、前回公開した記事の続編です。
- 「モニター開発」で進めたら、いい感じの話
- 【Rails × Devise】初心者エンジニアがユーザー認証を実装してみた話
- Rails × Devise × Basic認証】管理画面のセキュリティと使いやすさを両立した話
- Rails】初心者エンジニアが削除ボタンが動かない話!!原因はJavaScriptの・・
- 【Rails × 管理画面】namespaceで管理者用施術メニュー管理機能を実装してみた話
- 【Rails予約システム】時間枠の重複を防ぐバリデーションを実装した話(コピペOK)
🎯 実現したこと
- 予約フォームビュー(new.html.erb)で、メニューと予約時間を動的に選択可能に
- Reservationモデルを作成(user_id, menu_id, slot_idを持つ)
- 予約の重複を防止するバリデーションをReservationモデルに実装
🔑 この記事のKEYコード
Rails予約フォームビューの実装(これを使っています)
<%= form_with model: [:users, @reservation], local: true do |f| %>
<% if @reservation.errors.any? %>
<div class="error-messages">
<ul>
<% @reservation.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div>
<%= f.label :menu_id, "施術メニュー" %><br>
<%= f.collection_select :menu_id, @menus, :id, :name, prompt: "選択してください" %>
</div>
<div>
<%= f.label :slot_id, "予約時間帯" %><br>
<%= f.collection_select :slot_id, @slots, :id, :display_time_range, prompt: "選択してください" %>
</div>
<div>
<%= f.submit "予約する" %>
</div>
<% end %>
予約時間の重複を防ぐバリデーションの実装
# app/models/reservation.rb
class Reservation < ApplicationRecord
belongs_to :user
belongs_to :slot
belongs_to :menu
validates :user_id, :slot_id, :menu_id, presence: true
validate :slot_must_be_available
private
def slot_must_be_available
existing = Reservation.find_by(slot_id: slot_id)
if existing && existing.id != self.id
errors.add(:slot_id, "はすでに他のユーザーに予約されています")
end
end
end
なぜこのバリデーションが必要?
- 複数ユーザーが同じ時間帯(slot_id)を重複して予約しないようにするため
- 編集時は自身の予約は除外し、他の予約と重複しないかチェックこれにより、予約の信頼性とユーザー体験を守れ
まとめ
- 予約機能実装で、ユーザー体験を大きく左右する重要な部分が重複を防ぐバリデーション設計だと感じました。
- これから予約サイトを作る方、Rails初心者の方にとって、この記事が参考になれば幸いです。
📚 モニター開発中!!
🧑💻 Railsで予約システム「sorairo note」開発中!
開発途中での学び、失敗などを発信中🌈
→ 他の機能も記事で公開してます!
🌟 LGTM やシェアしてもらえると励みになります!