代码之家  ›  专栏  ›  技术社区  ›  Sonfaya

查询数据库中包含related_model的模型,其中相关模型有两个特定的id

  •  0
  • Sonfaya  · 技术社区  · 2 年前

    在rails应用程序中,我有一个3个模型,Room、User和UsersRoom,这是Room和User之间的关联表。 我想查询与多个用户相关的房间。

    如果我这样做:

    Room.includes(:users_rooms).where(users_rooms: { user_id: user_ids }
    

    我得到了至少有一个users_room的所有房间,其中包含一个user_id。 我想得到每个user_id都有user_rooms的房间。

    有没有一种干净的方法可以做到这一点,而不必在查询房间后在房间上循环?

    1 回复  |  直到 2 年前
        1
  •  1
  •   spickermann    2 年前

    我会尝试以下方法:

    Room
      .select('rooms.*, COUNT(users_rooms.user_id)')
      .joins(:users_rooms)
      .where(users_rooms: { user_id: user_ids })
      .group('rooms.id')
      .having('COUNT(users_rooms.user_id) >= ?', user_ids.size)
    

    注意事项:

    • 这个 COUNT 在中 select 是必需的,因为某些数据库引擎版本在使用时会抱怨 计数 在中 having 而没有在中定义 选择 部分你可以试着删除那条线。
    • 这个 join 做一个 INNER JOIN 在两张桌子之间。
    • 这个 where 是你已经想要的。
    • 这个 group 将找到的记录分组为一行,并允许使用 计数 。
    • 这个 有 只返回那些 rooms 至少 user_ids.size users_rooms 关联。
        2
  •  0
  •   max Mike Williams    2 年前

    我会这样做:

    class Room
      # ...
      has_many :users, though: :users_rooms
    end
    
    Room.group(:id)
        .joins(:users)
        .where(users: { id: user_ids })
        .having(User.arel_table[:id].count.gte(user_ids.size))
    

    创建间接关联是可选的,但抽象使得查询不与联接表的实现方式绑定。

    例如 UsersRoom 不是一个好名字,你可能想叫它更合适的名字,比如 Booking -这可以让你在不破坏任何东西的情况下做到这一点。

    推荐文章