【问题标题】:Ruby on Rails lambda with left join and condition带有左连接和条件的 Ruby on Rails lambda
【发布时间】:2021-09-15 08:29:14
【问题描述】:

房间有_many预订

预订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

【问题讨论】:

  • 谢谢!但在这种情况下,我只会收到在该日期有预订的房间。我需要的 - 所有在该日期没有预订的房间 + 在该日期有预订但总预订量
  • 你可以在你的查询中添加有和组子句吗? .having("COUNT(date) &lt; 3").group(:id)

标签: ruby-on-rails ruby lambda


【解决方案1】:

更新 为了满足您实际上需要复杂连接的要求,请尝试以下操作

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 个,它应该会按要求显示。

【讨论】:

  • 感谢您的帮助! @engineersmnky 它几乎可以工作,但在这种情况下,我有: - 所有空房间(根本没有预订) - 在 SOME_DATE 预订的所有房间,总金额
  • @Irina 我明白了。使用 2 个条件连接进行了相应更新。
  • 再次感谢您!我收到此错误,无法真正找到问题... "SQLite3::SQLException: ambiguous column name: main.rooms.id"
  • @Irina 我不知道这怎么可能被认为是模棱两可的,这对我来说似乎完全有资格。此外,我强烈建议使用生产就绪数据库,例如postgreSQL、mySQL、mariaDB、MSSQL 等。SQLite 有很多怪癖,其中大部分我不够熟悉,无法真正提供足够的帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-04-01
  • 1970-01-01
  • 2021-03-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-28
相关资源
最近更新 更多