使用 ActiveRecord 搜索对象的关联和 return 个实例,其中所有关联 do/do 不包含特定值
Using ActiveRecord to search through an object's associations and return instances where all of the associations do/do not contain a certain value
我正在尝试查询一个对象的关联,并且只查询所有关联都具有特定值的 return 个对象。例如,如果 User 有一个 memberships 关联,并且 memberships 有一个 active(boolean) 字段,我想 return 仅具有 active: false 会员资格的所有用户的集合。
我现在正在处理的查询是:
User.includes(:memberships).where(memberships: {active: false})
但是,这为我提供了所有拥有非活动会员资格的用户,以及同时拥有 活动:false 和 活动:true[=31= 的所有用户] 会员资格。我尝试对此进行额外的 .where.not,但当然,return 编辑了同一组。
我考虑过映射用户集合并创建一个新数组,踢出具有活跃会员资格的用户,但我需要将最终值保留为 AR 集合,因为我继续在控制器。
我宁愿为此坚持使用 ActiveRecord,但如果它不可行并且我需要使用 SQL,我也愿意这样做。
如有任何帮助,我们将不胜感激。谢谢!
要排除具有有效和无效成员资格的用户,请尝试--
User.includes(:memberships).where(memberships: {active: false}).where.not(memberships: {active: true})
另外——您可能想使用#joins 而不是#includes。如果除了查询之外不需要访问成员身份,则无需将其加载到内存中(#include 会这样做)。
这篇文章有一个很好的解释——
http://tomdallimore.com/blog/includes-vs-joins-in-rails-when-and-where/
此处有两点 - 您需要 LEFT OUTTER 联接,因此请确保您的 SQL 查询构建正确。检查
User.includes(:memberships).where(memberships: {active: false}).explain
或
User.includes(:memberships).where(memberships: {active: false}).to_sql
其次,尝试:
User.joins(:memberships).where("memberships.active = ?", false)
或者试试 .merge
,我喜欢用它:
User.joins(:memberships).merge(Membership.inactive)
假设您在 Membership
模型
上有一个 scope/class 方法 .inactive
def self.inactive
where(active: false)
end
.includes
真的只应在需要将关系加载到内存中时使用。
编辑:
排除任何拥有一个(或多个)成员资格的用户的最简单方法是将其分成 2 个查询。
active_user_ids = Membership.active.pluck(:user_id).uniq
User.where("id NOT IN (?)", active_user_ids.join(","))
我正在尝试查询一个对象的关联,并且只查询所有关联都具有特定值的 return 个对象。例如,如果 User 有一个 memberships 关联,并且 memberships 有一个 active(boolean) 字段,我想 return 仅具有 active: false 会员资格的所有用户的集合。
我现在正在处理的查询是:
User.includes(:memberships).where(memberships: {active: false})
但是,这为我提供了所有拥有非活动会员资格的用户,以及同时拥有 活动:false 和 活动:true[=31= 的所有用户] 会员资格。我尝试对此进行额外的 .where.not,但当然,return 编辑了同一组。
我考虑过映射用户集合并创建一个新数组,踢出具有活跃会员资格的用户,但我需要将最终值保留为 AR 集合,因为我继续在控制器。
我宁愿为此坚持使用 ActiveRecord,但如果它不可行并且我需要使用 SQL,我也愿意这样做。
如有任何帮助,我们将不胜感激。谢谢!
要排除具有有效和无效成员资格的用户,请尝试--
User.includes(:memberships).where(memberships: {active: false}).where.not(memberships: {active: true})
另外——您可能想使用#joins 而不是#includes。如果除了查询之外不需要访问成员身份,则无需将其加载到内存中(#include 会这样做)。
这篇文章有一个很好的解释—— http://tomdallimore.com/blog/includes-vs-joins-in-rails-when-and-where/
此处有两点 - 您需要 LEFT OUTTER 联接,因此请确保您的 SQL 查询构建正确。检查
User.includes(:memberships).where(memberships: {active: false}).explain
或
User.includes(:memberships).where(memberships: {active: false}).to_sql
其次,尝试:
User.joins(:memberships).where("memberships.active = ?", false)
或者试试 .merge
,我喜欢用它:
User.joins(:memberships).merge(Membership.inactive)
假设您在 Membership
模型
.inactive
def self.inactive
where(active: false)
end
.includes
真的只应在需要将关系加载到内存中时使用。
编辑:
排除任何拥有一个(或多个)成员资格的用户的最简单方法是将其分成 2 个查询。
active_user_ids = Membership.active.pluck(:user_id).uniq
User.where("id NOT IN (?)", active_user_ids.join(","))