【发布时间】:2015-04-10 00:18:13
【问题描述】:
如果给定房间已经存在预订,则该代码可以正常检测重叠日期以不保存预订。但是,我不得不扭曲我的代码以使其工作,因为验证会使我的控制器中的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
所以我的问题是如何使我的控制器中的代码更好,以便在保存 Booking 而不是更新时进行验证
【问题讨论】:
-
您的意思是只希望在首次创建记录并保存到磁盘时运行验证,而不是在后续更新时运行?
-
我想要的是在我的控制器内部,不必验证 update == true 是否继续。问题是我的验证仍然保存 end_date 为 nil 的预订,而不是抛出错误,所以在我的控制器中,我必须验证
@room.bookings.last.update (true?)是否没有这个问题。我的验证使更新== false,而我认为应该是== false 的保存。我想了解为什么它不会像这样发生。
标签: sql validation ruby-on-rails-4 code-readability