[英]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.