【问题标题】:Query for all of a specific record where its related resource all have the same value for a single attribute查询所有特定记录,其中其相关资源都具有单个属性的相同值
【发布时间】:2014-01-08 18:08:52
【问题描述】:
class User < ActiveRecord::Base
has_many :memberships

# included columns
# id: integer

---------------------

Membership < ActiveRecord::Base
belongs_to :user

# included columns
# user_id: integer
# active: boolean

我希望能够在单个查询中获取所有会员资格都为“active = false”的所有用户。到目前为止,我能想到的最好的是:

#grab possibles
users = User.joins(:memberships).where('memberships.active = false')
#select ones that satisfy condition
users.select{ |user| user.memberships.pluck(&:active).uniq == [false] } 

这不是很好,因为我必须使用 ruby​​ 来提取有效的。

【问题讨论】:

    标签: sql ruby-on-rails ruby activerecord


    【解决方案1】:

    这可以解决问题:

    users_with_active_membership = User.joins(:memberships).where(memberships: { active: true })
    users = User.where( 'users.id NOT IN (?)', users_with_active_membership.pluck(:id) )
    

    我不确定结果,但我希望它是 2 个嵌套查询,一个选择具有活动成员资格的用户 ID,另一个查询选择不在此先前 ID 列表中的用户。

    我无法测试它,因为我没有具有这些关系的环境。您可以尝试一下并发布生成的 SQL 查询吗? (加.to_sql查看)

    另一种方式,我不知道哪种方式最有效:

    User.where( 'users.id NOT IN (?)', Membership.where(active: true).group(:user_id).pluck(:user_id) )
    

    【讨论】:

    • 这是一个很棒的镜头,但仍然触发了两个查询。目标是在单个查询中加入和比较值,而无需执行子查询。我怀疑使用带有别名的“有”和“不在”可能是诀窍。我将上述问题描述更改为使用“pluck”进行小优化,而不是使用 map。感谢您的回答!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-21
    • 2018-01-08
    • 1970-01-01
    相关资源
    最近更新 更多