Rails Activerecord: как исключить записи с несколькими связанными записями - PullRequest
0 голосов
/ 13 сентября 2018

У меня есть запрос ниже с ассоциациями, как показано.

Запрос работает, когда для велосипеда имеется только одна запись о бронировании, но он не выполняется, если у велосипеда несколько бронирований, и одна или несколько из них соответствуют условиям, а другие - нет. Поскольку другие не удовлетворяют условиям, они приводят к тому, что соответствующий велосипед возвращается в результате.

Как мне написать запрос, чтобы велосипед не возвращался в качестве результата запроса, когда хотя бы одна из бронирований соответствует условию 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)

Ответы [ 3 ]

0 голосов
/ 13 сентября 2018

Я думаю, вы можете немного упростить условие.Я не рассматривал крайние случаи, но вы можете сделать что-то вроде этого:

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

Так что в основном bookings.start_time должно быть меньше, чем потенциал endDate, тогда как bookings.end_time больше, чем потенциал startDate.Следовательно, вы получите все заказы, которые находятся в диапазоне потенциального нового диапазона времени бронирования, и добавление not выберет противоположное

Я проверил свой образец на простом наборе данных, и он исключает велосипеды, которые являютсязанятыми.Пожалуйста, дайте мне знать, если это работает для вас

0 голосов
/ 13 сентября 2018

Вы можете поменять местами, начав запрос с желаемых бронирований и найдя набор всех их уникальных велосипедов:

@bikes = Booking.where.not(...).group(:bike_id).includes(:bikes).map{|b| b.bike}
0 голосов
/ 13 сентября 2018

Вы можете выполнить запрос на Bike с подзапросом на Booking:

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