简体   繁体   中英

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?

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.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 . 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

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}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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