我想搜索不属于第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)
答案 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获得了它。
我没有测试它。所以你可以尝试使用具体的语法。