Rails ActiveRecord如何查找记录未与特定其他记录连接的所有记录?

时间:2015-06-07 11:04:00

标签: ruby-on-rails activerecord

我想搜索不属于第1组(Users)的所有用户(Groups),加入UserGroups,即"找到所有用户没有UserGroups记录将它们绑定到组1。"

我可以找到User.all的所有用户,或者使用User.where('name like ?' , '%'+params[:search]+'%')

按名称查找

我甚至可以找到那些没有会员资格的人:

User.includes(:user_groups).where( :user_groups => { :user_id => nil } )

但是我怎么说,"找到不属于第1组成员的所有Users?"

更新:这是有效的SQL:

select * from Users as u where not exists (select 1 from UserGroups where group_id = 1 and user_id = u.id);

或者,如果您更喜欢缓存的NOT IN

select * from Users as u where u.id not in (select user_id from UserGroups where group_id = 1);

更新:

我发现现在只做原始SQL的方法,但是会喜欢真正的ActiveRecord方法:

User.where('name like ? and id not in (select user_id from UserGroups where group_id = ?)' , '%'+params[:search]+'%',@group.id)

2 个答案:

答案 0 :(得分:2)

此:

select user_id from UserGroups where group_id = 1;

......基本上是:

@group.user_groups.select(:user_id)
  • has_many关联中存在这样的方法。对于构建子查询,似乎。

所以这个:

select * from Users as u
where u.id not in (select user_id from UserGroups where group_id = 1);

这是:

User.where.not(id: @group.user_groups.select(:user_id))
  • 条件中的值为Relation,因此它作为子查询嵌入。

而且:

select * from Users as u
where not exists
  (
    select 1 from UserGroups
    where group_id = 1 and user_id = u.id
  );

是......唯一棘手的部分是我们必须引用外表的值,这在查询中不是常量。所以我们必须以另一种方式引用表格字段。有点Arel会这样做:

users = User.arel_table # `arel_table` is a sign of some serious SQL business
User.where(@group.user_groups.where(user_id: users[:id]).exists.not)

您可能还想查看one of my other recent answers about NOT EXTSTS

你也可以使用来自" {"}的ids,但是我不知道它是否会从连接模型中获取它们,而不是连接模型。

答案 1 :(得分:0)

在where子句中尝试使用'field not in list',如此。

User.includes(:user_groups).where('user_id not in (?)', :group_1_id)

group_1_id替换为您案例中第1组的标识符。 我从question获得了它。

我没有测试它。所以你可以尝试使用具体的语法。