Rails 3范围 – 查找不在特定组中的用户

这是我的问题(有点简化):

我有以下型号:

class User has_many :group_users has_many :groups, through: :group_users class Group has_many :group_users has_many :users, through: :group_users class GroupUser belongs_to :group belongs_to :user scope :belonging_to_group ->(group) {where(group_id = group.id)} 

我想对不在一个特定组中的用户进行范围,让我们说蔬菜的例子,这样的事情会是这样的:

 scope :not_in_group, ->(group) 

我尝试过这样的条款:

 scope :not_in_group, ->(group) {joins(:group_users).merge(::GroupUser.belonging_to_group(group)).group(:title).having('count(group_users.user_id) = 0') 

但似乎没什么用

编辑 :我现在有另一个问题,你可能想要检查这个,如果你从另一个类的类方法调用你的范围: Rails – 使用另一个类方法的类方法与第二类的一个属性

试试这个

 scope :not_in_group, -> group_id {joins(:group_users).where('group_users.group_id != ?', group_id)} 

对于左连接,请尝试以下方法:

 scope :not_in_group, -> group_id {joins("left join group_users on users.id = group_users.user_id").where('group_users.group_id != ?', group_id)} 

根据rails文档:

使用类方法是接受范围参数的首选方法。 仍然可以在关联对象上访问这些方法。 资源。

 class User #... # Retrieve all users not in a specific group # example: User.not_in_group(Group.find(5)) def self.not_in_group(group) includes(:group_users).where("group_users.group_id != ?", group.id) end end 

如果您决定使用范围,那么它是:

 scope :not_in_group, ->(group) {includes(:group_users).where("group_users.group_id != ?", group.id)} 

编辑 :我意识到,如果用户有两个组,它就不能正常工作,因为他看起来并不是两个组。 我相信MySQL发现了另一个具有用户id和另一个group_id的group_users。

所以我改为这个,这似乎有效:

 scope :not_in_group, ->(group){ in_group = User.joins(:group_users).where("group_users.group_id = ?", group.id) where(arel_table[:id].not_in in_group.map(&:id)) } 

两次但工作。

以前的解决方案 :仅当您的用户有一个组时才有效。

最后我找到了一个解决方案,我必须在joins()where()传递原始SQL,就像@Himesh建议我做的那样。 非常感谢你和@ lightswitch05的帮助。

你的两个命题都没有选择没有任何组的用户,这是一个有效的解决方案:

  def not_in_group(group) joins('LEFT JOIN group_users ON group_users.user_id = users.id').where("group_users.group_id != ? OR group_users.group_id is null", group.id) end 

发现一些在那里举行: Rails 3 ActiveRecord where子句设置的子句或null