Ruby on rails 如何检查预订日期是否与rails酒店应用程序重叠

Ruby on rails 如何检查预订日期是否与rails酒店应用程序重叠,ruby-on-rails,ruby,Ruby On Rails,Ruby,我正在用RubyonRails为一家酒店制作一个web应用程序。我看到了一些问题,这些问题看起来可能和我的一样,但我找不到正确的解决方案 用户可以创建预订并选择他们想要的房间以及他们到达和离开的日期。一切都按照我想要的方式进行,除了我的房间可以用重叠的日期预订 模式: create_table "bookings", force: :cascade do |t| t.integer "user" t.integer "course" t.date "arriving_da

我正在用RubyonRails为一家酒店制作一个web应用程序。我看到了一些问题,这些问题看起来可能和我的一样,但我找不到正确的解决方案

用户可以创建预订并选择他们想要的房间以及他们到达和离开的日期。一切都按照我想要的方式进行,除了我的房间可以用重叠的日期预订

模式

create_table "bookings", force: :cascade do |t|
  t.integer  "user"
  t.integer  "course"
  t.date     "arriving_date"
  t.date     "leaving_date"
  t.boolean  "breakfast"
  t.text     "remarks"
  t.datetime "created_at",    null: false
  t.datetime "updated_at",    null: false
  t.integer  "room_id"
  t.integer  "user_id"
  t.index ["room_id"], name: "index_bookings_on_room_id", using: :btree
  t.index ["user_id"], name: "index_bookings_on_user_id", using: :btree
end

create_table "rooms", force: :cascade do |t|
  t.string   "room_number"
  t.integer  "room_type_id"
  t.datetime "created_at",   null: false
  t.datetime "updated_at",   null: false
  t.index ["room_type_id"], name: "index_rooms_on_room_type_id", using: :btree
end
控制器

  def new
    @booking = Booking.new
  end

  def create
    @booking = Booking.new(booking_params)
    if @booking.save
      redirect_to @booking
    else
      flash[:notice] = "Something went wrong"
      render 'index'
    end
  end
预订模式

class Booking < ApplicationRecord
  belongs_to :room
  belongs_to :user
end
订舱
我想要什么


当用户尝试创建预订时,他们应该无法选择在他们想在酒店住宿的日子已经预订的某个房间。

确定。您需要(在您的预订模型中)这样的内容:


将以下内容添加到您的预订模型中

before_create: check_date_availability

def self.check_date_availability(booking_params)
  bookings = Booking.where('arrival_date < ? OR leaving_date > ?', self.arrival_date, self.leaving_date)
  return bookings.empty?
end
创建前:检查\u日期\u可用性
定义自我检查日期可用性(预订参数)
预订=预订。其中('到达日期<或离开日期>?',self.arrival\u日期,self.leaving\u日期)
回程预订。空吗?
结束

请更改查询中的条件。和/或根据您的要求。

我已经尝试了给出的答案,但还不能让它起作用。所以我制定了自己的解决方案,但我还不满意,因为“胖模特,瘦控制器”的事情

这对我很有用:

def create
  @booking = Booking.new(booking_params)

  @date_start = @booking.arriving_date.strftime("%Y-%m-%d")
  @date_end = @booking.leaving_date.strftime("%Y-%m-%d")

  found = false
  @all_bookings = Booking.all
  @all_bookings.each do |booking|
    arival_date = booking.arriving_date.strftime("%Y-%m-%d")
    leave_date = booking.leaving_date.strftime("%Y-%m-%d")
    if @date_start.between?(arival_date, leave_date) || @date_end.between?(arival_date, leave_date)
      if booking.room_id == @booking.room_id
        found = true
      end
    end
  end

  if found == true
    redirect_to new_booking_path, notice: "This room is already booked in the period you want to book it"
  else
    @booking.save!
    redirect_to @booking
  end
end

我仍然对“正确”的答案感兴趣:)

在最粗糙的伪代码中,我将使用实例方法扩展空间

# room.rb
def is_available? time_range
  bookings.present?(:arrival < time_range.end AND :depature > timerange.start)
end
#room.rb
def可用吗?时间范围
预订。当前?(:到达timerange.start)
结束
在控制器中的创建操作中调用此选项,就像在自己的答案中一样


你肯定想这样做,而不是循环所有的预订

想知道你走了多远?显示您的验证method@Fallenhero我理解你为什么这么问,但问题是我完全不知道如何制作这样的东西……不要重复你的预订。您需要找到
ActiveRecord
或SQL解决方案。如果必须这样做,请不要使用
find
,而是使用
find\u each
(如果顺序不重要)。另外,在找到预订时提前停止(您的代码将检查所有预订,即使第一个预订重叠!)。Shabihi,您的函数不能只返回预订。空吗?没有必要使用if/else/end。是的,也可以。谢谢你抓到ZaurAmikishiyev。更新了答案。谢谢你的回答,我会试试看@StijnWesterhof可以自由编辑并给出真正的代码(可能编辑您自己的答案)。
# room.rb
def is_available? time_range
  bookings.present?(:arrival < time_range.end AND :depature > timerange.start)
end