对于酒店应用程序,我试图筛选出在给定的到达日期和出发日期的所有可用住宿,因此用户只将这些视为选项。
我目前的做法是,首先识别所有不可用的住宿,然后从所有住宿中扣除它们。
问题
当我想编辑预订时,我想:
时不包括当前的预订
因此,在==>语句中,对reservation.arrival和reservation.departure的保留及其可容纳性不会在查询语句中进行计算。
这是可能的吗?或者我如何才能在没有考虑到当前reservation.accommodation的情况下,只为送礼者提供住宿?
示例期望结果
码
模型
class Reservation < ApplicationRecord
belongs_to :hotel
belongs_to :accommodation
end
class Accommodation < ApplicationRecord
belongs_to :accommodation_category
has_many :reservations, dependent: :destroy
accepts_nested_attributes_for :accommodation_category
end
class Hotel < ApplicationRecord
has_many :accommodation_categories, dependent: :destroy
has_many :accommodations, through: :accommodation_categories
has_many :reservations, dependent: :destroy
end查询
@unavailable_accommodations = Accommodation.joins(:reservations).where(reservations: {hotel: hotel}).where("reservations.arrival <= ? AND ? <= reservations.departure", arrival, departure)
.or(Accommodation.joins(:reservations).where(reservations: {hotel: hotel}).where("reservations.arrival >= ? AND ? >= reservations.departure", arrival, departure)).distinct控制器动作
def accommodations_availability
#check if there was an accommodation for this reservation
if !params[:reservation].nil?
reservation = Reservation.find(params[:reservation])
@prev_accommodation = reservation.accommodation
@previous_cat = @prev_accommodation.accommodation_category
end
hotel = Hotel.includes(:accommodations).find(params[:id])
arrival = Date.parse(accommodation_params[:arrival])
departure = Date.parse(accommodation_params[:departure])
time_span = arrival..departure
#SQL statement
@unavailable_accommodations = Accommodation.joins(:reservations).where(reservations: {hotel: hotel}).where("reservations.arrival <= ? AND ? <= reservations.departure", arrival, departure)
.or(Accommodation.joins(:reservations).where(reservations: {hotel: hotel}).where("reservations.arrival >= ? AND ? >= reservations.departure", arrival, departure)).distinct
@hotel_cats = hotel.accommodation_categories
@hotel_accos = Accommodation.where(accommodation_category: @hotel_cats)
@accommodations = @hotel_accos - @unavailable_accommodations
@available_cats = []
@accommodations.each do |acco|
if !@available_cats.include? acco.accommodation_category
@available_cats << acco.accommodation_category
end
end
respond_to do |format|
format.js
end
end发布于 2020-01-10 11:54:11
为什么不简单地这样做:
@current_reservation = Reservation.find(params[:id]) # whatever it is
@unavailable_accommodations = your_query1
@available_accommodations = your_query2 - [@current_reservation.accommodation]更新:
在控制器端可以有一个解决方案,但我有一种感觉,这种事情也应该在前端处理。
建议:在填写更新表单时,您是否可以传递当前住宿的先前预订、出发和下一次预订到达。这样,您可以通过向这两个字段添加min和max值来限制编辑TimeDate字段。我希望你明白这个想法。
从设计(安全性)的角度来看,添加后端检查仍然很重要。我会考虑更多,并再次更新,希望:)
更新2: (以下问题评论)
“好吧,我认为tbh,这是你的设计中的一个问题--你在查询中计算available_accommodations,但你实际要向用户显示的是available_reservations。这就是为什么在脑海中想象这个问题如此混乱的原因。我希望你从这个角度来思考。你不一定需要改变设计(你可以将用户显示为可用的住宿,但查询应该更多地涉及场景背后的保留)。”
发布于 2020-01-23 01:47:13
您可以在一个查询中直接筛选出所有可用的住宿:
@available_accommodations = Accommodation.joins(
"LEFT OUTER JOIN accommodations
ON (reservations.hotel_id = accommodations.hotel.id
AND reservations.accommodation_id = accommodations.id
AND reservations.arrival <= ?
AND reservations.departure >= ?)", departure, arrival)
.where("accommodations.hotel_id = ?", params[:id])
.where("reservations.id IS NULL")
.select("accommodations.*")关键是连接条件reservations.arrival <= departure AND reservations.departure >= arrival。这意味着只有在预定到达和离开的范围内,才能参加预定的住宿。然后,它过滤掉可用的住宿与reservations.id IS NULL在联合表。
https://stackoverflow.com/questions/59680407
复制相似问题