ice_cube gemを使用して定期的な予約を処理する予約システムを作成しています。has_manyは、繰り返しルールの出現ごとに 1 つBooking
ずつBookingItem
あり、これらはBooking
の after_save コールバックによって呼び出されるメソッドで作成されます。
BookingItem
これは、特定の時間にまだ予約がないことを確認することで二重予約を回避する検証を追加するまで、すべて正常に機能していBookingItem
ました。この検証により、予約フォームに表示したいエラーが発生しますが、現時点では、 のフォームに戻されていないBooking
によってエラーが発生したため、 の保存が黙って妨げられています。BookingItem
Booking
アプリ/モデル/booking.rb
class Booking < ActiveRecord::Base
include IceCube
has_many :booking_items, :dependent => :destroy
after_save :recreate_booking_items!
# snip
private
def recreate_booking_items!
schedule.all_occurrences.each do |date|
booking_items.create!(space: self.requested_space,
booking_date: date.to_date,
start_time: Time.parse("#{date.to_date.to_default_s} #{self.start_time.strftime('%H:%M:00')}"),
end_time: Time.parse("#{date.to_date.to_default_s} #{self.end_time.strftime('%H:%M:00')}"))
end
end
end
アプリ/モデル/booking_item.rb
class BookingItem < ActiveRecord::Base
belongs_to :booking
validate :availability_of_space
# snip
private
def availability_of_space
unless space.available_between? DateTime.parse("#{booking_date}##{start_time}"), DateTime.parse("#{booking_date}##{end_time}")
errors[:base] << "The selected space is not available between those times."
end
end
end
アプリ/ビュー/予約/_form.html.erb
<% if @booking.errors.any? %>
<div id="error_explanation">
<p><%= pluralize(@booking.errors.count, "error") %> prohibited this booking from being saved:</p>
<ul>
<% @booking.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<%= form_for(@booking, :html => { :class => "nice custom"}) do |f| %>
...
<% end %>