Ruby on rails 4 使用ActiveRecord搜索对象';s关联并返回所有关联不包含/不包含特定值的实例

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。

我试图查询对象的关联,并且只返回所有关联都具有特定值的对象。例如,如果一个用户有一个成员关系关联,并且成员关系有一个活动(布尔)字段,我想返回一个所有用户的集合,这些用户的成员关系只有活动:false

我现在处理的问题是:

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语句中,只需拆分查询即可。除非你没有数百万的用户(加入这个字符串可能会很昂贵),否则这仍然非常有效。