Rails代码的可读性供我验证 [英] Rails code readability for my validation
问题描述
该代码可以很好地检测重叠的日期,如果给定房间已经存在预订,则不保存预订。但是,我不得不扭曲代码使其起作用,因为验证会使控制器中的 update
无效,而不是 save
。因此,我想知道我的代码出了什么问题,因为通常无效的代码应该应用于保存而不是更新。
The code works fine in detecting overlapping dates to not save a Booking if it already exist for a given Room. However, I had to twist my code to make it work because validation would make the update
in my controller not valid instead of the save
. So I want to know what is wrong with my code as normally the not valid should apply to the save and not the update.
实际上,告诉我预订无法保存而不是抛出错误,它只是没有更新我的contoller中的booking.end_date,而它在保存而不是在我尝试更新它时应该引发错误:
In fact, to tell me that a booking cannot be saved instead of throwing an error, it just did not update the booking.end_date in my contoller while it should raise an error when it save and not when I try to update it:
我有一个控制器可以为房间创建一个新的预订(这是我要改进的地方):
I have a controller that create a new booking for a room (this is what I want to improve):
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
新的预订要经过验证,以确保没有进行重复日期的预订:
The new booking go through validation to make sure no booking with overlapping date has been made:
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
所以我的问题是如何使我的代码在控制器中更好,以便验证在保存预订时有效,而不是在更新时有效
So my question is how to make my code in my controller better so that the validation will work when Booking is saved and not when it is updated
推荐答案
您可以执行类似的操作,在保存之前检查您对房间的所有预订,然后逐一检查条件。
You can do something like that, check all bookings that you assing to your room before save, and one by one check the condition.
def dates_are_available
room.bookings.each do |b|
if bookings.start_date
self.errors.add(:base, 'Date already taken')
end
end
end
这篇关于Rails代码的可读性供我验证的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!