Ruby on rails 4 使用ActiveRecord搜索对象';s关联并返回所有关联不包含/不包含特定值的实例
我试图查询对象的关联,并且只返回所有关联都具有特定值的对象。例如,如果一个用户有一个成员关系关联,并且成员关系有一个活动(布尔)字段,我想返回一个所有用户的集合,这些用户的成员关系只有活动:false 我现在处理的问题是:Ruby on rails 4 使用ActiveRecord搜索对象';s关联并返回所有关联不包含/不包含特定值的实例,ruby-on-rails-4,activerecord,associations,Ruby On Rails 4,Activerecord,Associations,我试图查询对象的关联,并且只返回所有关联都具有特定值的对象。例如,如果一个用户有一个成员关系关联,并且成员关系有一个活动(布尔)字段,我想返回一个所有用户的集合,这些用户的成员关系只有活动:false 我现在处理的问题是: User.includes(:memberships).where(memberships: {active: false}) 但是,这将为我提供所有具有非活动成员身份的用户,以及同时具有活动:false和活动:true成员身份的所有用户。我试着做了一个额外的。where。
User.includes(:memberships).where(memberships: {active: false})
但是,这将为我提供所有具有非活动成员身份的用户,以及同时具有活动:false和活动:true成员身份的所有用户。我试着做了一个额外的。where。不是这个,但当然,它返回了同一组
我考虑过映射用户集合并创建一个新数组,将具有活动成员身份的用户踢出,但我需要将最终值保留为AR集合,以便在控制器中进一步查询它
我更愿意坚持使用ActiveRecord来实现这一点,但如果这不可行,我需要使用SQL来代替,我也愿意这样做
任何帮助都将不胜感激。谢谢大家! 要排除具有有效和无效成员身份的用户,请尝试--
User.includes(:memberships).where(成员身份:{active:false}).where.not(成员身份:{active:true})
此外,您可能希望使用#连接而不是#包含。如果除了查询之外,您不需要访问成员身份,那么就不需要将其加载到内存中(include会这样做)
这篇文章有一个很好的解释--
要排除具有有效和无效成员身份的用户,请尝试--
User.includes(:memberships).where(成员身份:{active:false}).where.not(成员身份:{active:true})
此外,您可能希望使用#连接而不是#包含。如果除了查询之外,您不需要访问成员身份,那么就不需要将其加载到内存中(include会这样做)
这篇文章有一个很好的解释--
这里有两件事-您需要一个左撇子连接,因此请确保SQL查询的构造正确。核对
User.includes(:memberships).where(memberships: {active: false}).explain
或
第二,尝试:
User.joins(:memberships).where("memberships.active = ?", false)
或者尝试一下.merge
,我喜欢使用:
User.joins(:memberships).merge(Membership.inactive)
假设您在成员资格
模型上有一个作用域/类方法.inactive
def self.inactive
where(active: false)
end
.includes
仅在需要将关系加载到内存中时才应使用
编辑:
排除具有单个(多个)成员身份的任何用户的最简单方法是将其拆分为两个查询
active_user_ids = Membership.active.pluck(:user_id).uniq
User.where("id NOT IN (?)", active_user_ids.join(","))
这里有两件事-您需要一个左撇子连接,因此请确保SQL查询的构造正确。核对
User.includes(:memberships).where(memberships: {active: false}).explain
或
第二,尝试:
User.joins(:memberships).where("memberships.active = ?", false)
或者尝试一下.merge
,我喜欢使用:
User.joins(:memberships).merge(Membership.inactive)
假设您在成员资格
模型上有一个作用域/类方法.inactive
def self.inactive
where(active: false)
end
.includes
仅在需要将关系加载到内存中时才应使用
编辑:
排除具有单个(多个)成员身份的任何用户的最简单方法是将其拆分为两个查询
active_user_ids = Membership.active.pluck(:user_id).uniq
User.where("id NOT IN (?)", active_user_ids.join(","))
谢谢我已经确认我正在使用左外部联接。explain,并尝试了联接方法。不过我也遇到了同样的问题。如果用户同时具有活动和非活动成员身份,则仍将返回这些成员。@swats-我更新了答案。为了留在AR中,而不是陷入令人讨厌的SQL语句中,只需拆分查询即可。除非你没有数百万的用户(加入这个字符串可能会很昂贵),否则这仍然是非常有效的。谢谢!我已经确认我正在使用左外部联接。explain,并尝试了联接方法。不过我也遇到了同样的问题。如果用户同时具有活动和非活动成员身份,则仍将返回这些成员。@swats-我更新了答案。为了留在AR中,而不是陷入令人讨厌的SQL语句中,只需拆分查询即可。除非你没有数百万的用户(加入这个字符串可能会很昂贵),否则这仍然非常有效。