简体   繁体   English

Rails Activerecord:如何排除具有多个关联记录的记录

[英]Rails Activerecord: How to exclude records with multiple associated records

I have the below query with the associations as shown. 我有以下所示的关联查询。

The query works when there is only one booking record per bike, but fails when bike has multiple bookings and one or more meet the conditions and others do not. 当每辆自行车只有一个预订记录时,该查询起作用,但是当自行车有多个预订并且一个或多个满足条件而其他不满足条件时,查询将失败。 Since the other don't meet the conditions, they cause the associated bike to be returned as a result. 由于另一个不符合条件,因此会导致相关自行车退回。

How do I write the query so that a bike is not returned as a query result when at least one of the bookings meets the where.not condition? 如何编写查询,以便在至少一项预订满足where.not条件时不将自行车作为查询结果返回?

class Bike < ActiveRecord::Base
  has_many :bookings
end 

class Booking < ActiveRecord::Base
  belongs_to :bike
end 

startDate = Date.parse("2018-10-10")
endDate = Date.parse("2018-10-19")

@bikes = Bike.joins(:bookings).where.not("(date_start BETWEEN (?) AND (?)) OR (date_start BETWEEN (?) AND (?)) OR (((?) OR (?)) BETWEEN date_start AND date_end)", startDate, endDate, startDate, endDate, startDate, endDate)

You could run the query on Bike with a subquery on Booking : 您可以在Bike上运行查询,在Booking上使用子查询:

Bike.where.not(
  id: Booking.select('DISTINCT bike_id').where(...)
)

I think you can simplify the condition a bit. 我认为您可以稍微简化一下条件。 I have not considered edge cases but you can do something like this: 我没有考虑过极端情况,但是您可以执行以下操作:

Bike.where.not(
    id: Booking.where("start_time < ? and end_time > ?", endDate, startDate
).group(:bike_id))

So basically bookings.start_time should be less then potential endDate while bookings.end_time is bigger than potential startDate . 因此,基本上bookings.start_time应该小于潜在的endDatebookings.end_time大于潜在的startDate Hence you will get all bookings that are in the range of the potential new booking time range and adding not will select the opposite 因此,您将获得潜在的新预订时间范围内的所有预订, not添加则将选择相反的

I've tested my sample on a simple dataset and it excludes the bikes that are occupied. 我已经在一个简单的数据集上测试了样本,其中不包括占用的自行车。 Please let me know if that works for you 请让我知道是否适合您

您可以颠倒一切,从所需的预订开始查询,并找到所有独特自行车的集合:

@bikes = Booking.where.not(...).group(:bike_id).includes(:bikes).map{|b| b.bike}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM