Rails代码可读性,用于验证

时间:2015-04-10 00:18:13

标签: sql validation ruby-on-rails-4 code-readability

代码在检测重叠日期时工作正常,如果已经存在给定房间,则不保存预订。但是,我不得不扭曲我的代码才能使其正常工作,因为验证会使我的控制器中的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

所以我的问题是如何让我的控制器中的代码更好,这样验证将在保存时保存,而不是在保存时更新

1 个答案:

答案 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