sql - Rails code readability for my validation -
the code works fine in detecting overlapping dates not save booking if exist given room. however, had twist code make work because validation make update
in controller not valid instead of save
. want know wrong code not valid should apply save , not update.
in fact, tell me booking cannot saved instead of throwing error, did not update booking.end_date in contoller while should raise error when save , not when try update it:
i have controller create new booking room (this want improve):
def create_book_now @room = room.find(params[:room_id]) booking = @room.bookings.build(booking_params) if booking.save #i want not save if model validation not ok if @room.bookings.last.update(end_date: booking.start_date + booking.length.days) # have check if true validation work, sure 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 make sure no booking 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 taken') # end conditions = [] conditions << '(start_date >= :new_start_date , end_date >= :new_end_date)' conditions << '(start_date >= :new_start_date , end_date <= :new_end_date)' conditions << '(end_date between :new_start_date , :new_end_date)' conditions << '(start_date <= :new_start_date , 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 taken') return false end end end
so question how make code in controller better validation work when booking saved , not when updated
you can that, check bookings assing room before save, , 1 one check condition.
def dates_are_available room.bookings.each |b| if bookings.start_date self.errors.add(:base, 'date taken') end end end