簡體   English   中英

如何在Rails中檢查時間范圍是否重疊? (類似於Airbnb的應用)

[英]How to check if a time range is overlapping in Rails ? (Airbnb like application)

我正在嘗試開發類似Airbnb的Rails應用程序,但是由於重疊的檢查系統而受阻; 當我們檢查該地點是否已被預訂時。 這里的困難是我需要檢查日期是否重疊,但也要檢查時間。 因為在我的項目中,您只可以在需要時租幾個小時。

架構:

  create_table "bookings", force: :cascade do |t|
    t.integer "user_id"
    t.integer "place_id"
    t.datetime "start_time"
    t.datetime "end_time"
    t.integer "price"
    t.integer "total"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.index ["place_id"], name: "index_bookings_on_place_id"
    t.index ["user_id"], name: "index_bookings_on_user_id"
  end

  create_table "places", force: :cascade do |t|
    t.integer "user_id"
    t.string "name"
    t.integer "price"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.index ["user_id"], name: "index_places_on_user_id"
  end

您是否有想法以干凈的方式實施此重疊檢查?

您想要的是一個BETWEEN查詢:

booked = Place.joins(:bookings)
  .where('? BETWEEN bookings.start_time AND bookings.end_time OR 
          ? BETWEEN bookings.start_time AND bookings.end_time', 
          starts_at, ends_at)

您可以創建一個范圍方法以避免重復此操作:

class Booking
  def self.between(starts_at, ends_at)
    where(
     '? BETWEEN bookings.start_time AND bookings.end_time OR ? BETWEEN bookings.start_time AND bookings.end_time', 
     starts_at, ends_at
    )
  end
end

由於.joins創建左內部.joins僅返回.joins表中具有匹配項的行。 要獲得逆,最簡單的方法是在兩個查詢中進行操作:

available = Place.where.not(id: booked)

您還可以使用左外部聯接:

available = Place.left_outer_joins(:bookings)
     .where(bookings: Booking.between(starts_at, ends_at))
     .where(bookings: { id: nil })

這將從bookings匹配的places刪除所有行。 .left_outer_joins已在Rails 5中添加。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM