代码在检测重叠日期时工作正常,如果已经存在给定房间,则不保存预订。但是,我不得不扭曲我的代码才能使其正常工作,因为验证会使我的控制器中的update
无效而不是save
。所以我想知道我的代码有什么问题,因为通常无效应该适用于保存而不是更新。
事实上,告诉我无法保存预订而不是抛出错误,它只是没有更新我的控制器中的booking.end_date,而它应该在保存时引发错误,而不是在我尝试更新时:
我有一个控制器为房间创建一个新的预订(这是我想要改进的):
def create_book_now
@room = Room.find(params[:room_id])
booking = @room.bookings.build(booking_params)
if booking.save #I want to not save if model validation are not OK
if @room.bookings.last.update(end_date: booking.start_date + booking.length.days) # I have to check if this is true for my validation to work, I am sure it is not normal
flash[:notice] = "Booking done"
redirect_to root_path
else
flash[:error] = "booking.errors.full_messages.first if booking.errors.any?"
redirect_to room_book_now_path(@room.id)
end
else
flash[:error] = booking.errors.full_messages.first if booking.errors.any?
redirect_to room_book_now_path(@room.id)
end
end
新预订将通过验证,以确保没有重叠日期的预订:
class Booking < ActiveRecord::Base
belongs_to :room
validates :length, :presence => true
validate :dates_are_available
def dates_are_available
room = Room.find(self.room_id)
# if Room.find(self.room_id).bookings.exists?
# self.errors.add(:base, 'Date already taken')
# end
conditions = []
conditions << '(start_date >= :new_start_date AND end_date >= :new_end_date)'
conditions << '(start_date >= :new_start_date AND end_date <= :new_end_date)'
conditions << '(end_date BETWEEN :new_start_date AND :new_end_date)'
conditions << '(start_date <= :new_start_date AND end_date >= :new_end_date)'
if room.bookings.where(conditions.join(' OR '), new_start_date: self.start_date, new_end_date: self.end_date).exists?
self.errors.add(:base, 'Date already taken')
return false
end
end
end
所以我的问题是如何让我的控制器中的代码更好,这样验证将在保存时保存,而不是在保存时更新
答案 0 :(得分:0)
您可以这样做,检查您在保存前分配给您房间的所有预订,并逐个检查条件。
def dates_are_available
room.bookings.each do |b|
if bookings.start_date
self.errors.add(:base, 'Date already taken')
end
end
end