Ruby on Rails lambda与左连接和条件



房间已预订

预订belongs_to房间

我有这个代码,它工作得很好:

available_rooms = Room.select {|room| room.bookings.where("day = ?", date).count < 3 || room.bookings.empty?}

但我想知道是否有可能将其重写为具有左连接的lambda

scope :available, lambda {|date| joins('LEFT OUTER JOIN bookings on bookings.room_id = rooms.id').......

我试了一下,但只得到至少有一个预订的房间,所以完全没有预订的空房间被排除在外:

def self.available(date)
# You can use `Arel.star` instead of `:id` on postgres.
b = Booking.arel_table[:id]
group(:id)
.left_joins(:bookings)
.where(bookings: { day: date })
.having(b.count.lt(3)) # COUNT(bookings.id) < 3
end

UPDATE要满足要求,您实际上需要一个复杂的连接,请尝试以下

class Room < ApplicationRecord
def self.available(date)
b = Booking.arel_table
join_statement = Arel::Nodes::OuterJoin.new(b,
Arel::Nodes::On.new(
arel_table[:id].eq(b[:room_id])
.and(b[:day].eq(Arel::Nodes.build_quoted(date)))
))
group(:id)
.joins(join_statement)
.having(b[:id].count.lt(3))
end
end

这里我们根据房间和请求日期的关系左加入bookings。现在,如果一个房间在那个日期没有被预订,或者在那个日期预订的房间少于3个,它应该按照要求显示。

最新更新