Rails代码的可读性供我验证 [英] Rails code readability for my validation

查看:75
本文介绍了Rails代码的可读性供我验证的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

该代码可以很好地检测重叠的日期,如果给定房间已经存在预订,则不保存预订。但是,我不得不扭曲代码使其起作用,因为验证会使控制器中的 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆