首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >SQL查询rails,如何过滤我们当前的预订

SQL查询rails,如何过滤我们当前的预订
EN

Stack Overflow用户
提问于 2020-01-10 11:03:31
回答 2查看 224关注 0票数 1

对于酒店应用程序,我试图筛选出在给定的到达日期和出发日期的所有可用住宿,因此用户只将这些视为选项。

我目前的做法是,首先识别所有不可用的住宿,然后从所有住宿中扣除它们。

问题

当我想编辑预订时,我想:

  • 在评估可用住宿

时不包括当前的预订

因此,在==>语句中,对reservation.arrivalreservation.departure的保留及其可容纳性不会在查询语句中进行计算。

这是可能的吗?或者我如何才能在没有考虑到当前reservation.accommodation的情况下,只为送礼者提供住宿?

示例期望结果

  • 说reservation_1 books accommodation_1从1月1日到1月2日,
  • 还有reservation_2从1月5日到1月6日,
  • ,当我随后编辑reservation_1并将离开更改为1月6日,accommodation_1不应被标记为可用,因为reservation_2已经预订了这个

模型

代码语言:javascript
复制
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

查询

代码语言:javascript
复制
@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

控制器动作

代码语言:javascript
复制
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
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-01-10 11:54:11

为什么不简单地这样做:

代码语言:javascript
复制
@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。这就是为什么在脑海中想象这个问题如此混乱的原因。我希望你从这个角度来思考。你不一定需要改变设计(你可以将用户显示为可用的住宿,但查询应该更多地涉及场景背后的保留)。”

票数 1
EN

Stack Overflow用户

发布于 2020-01-23 01:47:13

您可以在一个查询中直接筛选出所有可用的住宿:

代码语言:javascript
复制
@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在联合表。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59680407

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档