【问题标题】:Rails, querying associated records with conditionsRails,查询有条件的关联记录
【发布时间】:2015-01-15 16:19:14
【问题描述】:

我有一个 User-Group 与连接表 (group_partecipations) 的多对多关联,该连接表还有一个附加的“状态”列,该列采用以下值:

  • "owner"(当给定的 group_iduser_id 对没有其他记录时自动设置:这意味着该用户是创建者/该组的所有者)

  • “待定”(这是当用户加入群组但他们不是创建者时设置的默认值,这意味着他们正在等待群组创建者接受他们)

  • “接受”(当创建者接受待处理用户时)

我知道对于 DB 规范化规则,我应该在另一个表中提取此列,但现在我将保留它。

所以.. 现在,我正在尝试为给定用户创建一个查询,返回他拥有的所有组,以及该组的处于“待定”状态的用户。

虽然我找到了解决方案,但感觉很复杂,我真的不确定这是一个好方法,所以我想请教一些建议。

这是我想出的:

首先我找到用户是所有者的所有组:

groups_where_owner = u.groups.where(group_partecipations: {status: "owner" })

# u.groups would return all groups: 
# either those in which user is owner and those where he is pending or has been accepted

然后对于他自己的每个组,我返回一个由组本身和“待定”用户组成的数组:

groups_where_owner.map { |g| 
      [ g, 
        User.includes(:group_partecipations).where
        (:group_partecipations => {:group_id => g.id, status: "pending" })
      ]
}

但正如我所说,这感觉很脏而且“手工制作”太多,我试图了解我是否没有错过 ActiveRecord 中的一个重要部分以处理这种情况。

此外,当我将结果转换为 JSON 对象时,它有一个额外的嵌套级别,我想避免这种情况。

那么..有更好的方法吗?或者,正确的方法是什么

提前感谢您的帮助。

编辑:我的问题的重点是:有没有办法修改我的 AR 查询以过滤掉(或首先避免包括)所有未“待定”的用户(“所有者”和"accepted"s) 以便以后不必迭代查询结果来收集那些“待定”s?

【问题讨论】:

    标签: ruby-on-rails activerecord many-to-many associations


    【解决方案1】:

    这是一个完全可以接受的解决方案。

    但是可以改进它以减少对数据库的查询。目前,您对每个owned_group 执行单独的查询。 IO 操作比 cpu 操作慢数倍。因此,一次加载所有必要的数据然后进行处理是一个更好的策略。

    Group.includes(group_participations: :user)
      where(group_participations: {status: "pending" }).
      where(id: user.groups.where(group_participations: {status: "owner" }).ids).
      map { |g| [g, g.users]} 
    

    【讨论】:

    • 谢谢,但我的问题的重点是:有没有办法从查询中过滤掉(或避免首先包括)所有不是“待定”(“所有者” s 和 "accepted"s) 所以以后不必迭代查询结果来收集那些 "pending"s" 吗?我正在尝试学习 AR 查询,所以我想先了解如何挤出最大值如果我还没有完全做到这一点,它(从数据库中得到我需要的东西)。之后我将进行优化(并且已经感谢你为我提供了一些有用的见解)。
    • 我也不明白 (group_participations: :users) 中嵌套关联的包含背后的原因? AR 给出了一个错误,即“group_partecipation”上没有“用户”关联。如果我以单数形式“:user”键入嵌套关联,则没有错误,但我不知道这是什么意思..
    • 请在问题中添加确切的关系定义。我没有运行查询,但它应该只包括您所说的所需用户。我明天会详细检查一下
    • 编辑了答案。连接部分不是必需的,因为 ActiveRecord 只能从:includes 中找出它。错误也是(group_participations: :users),它应该是:user(group_participation 模型中的关联名称)。查看查询产生的日志,它将只包含pending 用户,而没有其他用户,这是通过where(group_participations: {status: "pending" }) 查询实现的
    猜你喜欢
    • 2016-01-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-08
    • 2021-04-17
    • 1970-01-01
    相关资源
    最近更新 更多