【问题标题】:Rails code readability for my validation我验证的 Rails 代码可读性
【发布时间】: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


【解决方案1】:

您可以这样做,在保存之前检查您分配到房间的所有预订,并一一检查条件。

def dates_are_available
    room.bookings.each do |b|
        if bookings.start_date
            self.errors.add(:base, 'Date already taken')
        end
    end
end

【讨论】:

  • 不,问题不在验证码中。而且您的代码不会验证所有可能的日期重叠。
猜你喜欢
  • 2014-03-11
  • 2014-12-30
  • 1970-01-01
  • 2011-02-17
  • 1970-01-01
  • 2015-05-17
  • 1970-01-01
  • 1970-01-01
  • 2018-02-12
相关资源
最近更新 更多