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

Ruby on rails Rails Activerecord:如何排除具有多个关联记录的记录,ruby-on-rails,ruby,rails-activerecord,Ruby On Rails,Ruby,Rails Activerecord,我有下面的查询,其关联如图所示 当每辆自行车只有一个预订记录时,查询工作,但当自行车有多个预订且一个或多个符合条件而其他不符合条件时,查询失败。由于另一辆不符合条件,因此导致相关自行车被退回 如何编写查询,以便在至少一个预订满足where.not条件时,自行车不会作为查询结果返回 class Bike < ActiveRecord::Base has_many :bookings end class Booking < ActiveRecord::Base belongs

我有下面的查询,其关联如图所示

当每辆自行车只有一个预订记录时,查询工作,但当自行车有多个预订且一个或多个符合条件而其他不符合条件时,查询失败。由于另一辆不符合条件,因此导致相关自行车被退回

如何编写查询,以便在至少一个预订满足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)
class Bike
您可以在
Bike
上运行查询,并在
Booking
上执行子查询:

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

我想你可以把条件简化一点。我没有考虑边缘情况,但您可以这样做:

Bike.where.not(
    id: Booking.where("start_time < ? and end_time > ?", endDate, startDate
).group(:bike_id))
Bike.where.not(
id:Booking.where(“开始时间<?和结束时间>”,endDate,startDate
).组(:bike_id))
所以基本上
预订。开始时间
应该小于潜在的
结束日期
,而
预订。结束时间
大于潜在的
开始日期
。因此,您将获得潜在新预订时间范围内的所有预订,添加
not
将选择相反的预订时间范围


我在一个简单的数据集上测试了我的样本,它排除了有人占用的自行车。请让我知道这是否适用于您

您可以将事情颠倒过来,从您想要的预订开始查询,并找到他们所有独特自行车的集合:

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

使用
bike\u id=ActiveRecord::Base.execute(SQL)
,然后执行类似于
bike.joins(:bookings.where(id:bike\u id)
)的操作,而不必创建模型。感谢您的回复!我选择了上面的一个答案,但我需要把最后一点分成两部分来简化它。真漂亮!非常感谢。