Rails ActiveRecord:查找当前用户以外的所有用户

时间:2010-04-20 05:23:35

标签: ruby-on-rails ruby activerecord

我觉得这应该很简单,但我的大脑正在短路。如果我有一个表示当前用户的对象,并且想要查询除​​当前用户以外的所有用户,我该怎么做呢,考虑到当前用户有时可能是nil

这就是我现在正在做的事情:

def index
  @users = User.all
  @users.delete current_user
end

我不喜欢的是我正在对查询结果进行后处理。除了感觉有点不对外,如果我将查询转换为与will_paginate一起运行,我认为这不会很好。有关如何使用查询执行此操作的任何建议?感谢。

11 个答案:

答案 0 :(得分:136)

可以在Rails 4中执行以下操作:

User.where.not(id: id)

你可以将它包装在一个很好的范围内。

scope :all_except, ->(user) { where.not(id: user) }
@users = User.all_except(current_user)

如果您愿意,可以使用类方法:

def self.all_except(user)
  where.not(id: user)
end

两种方法都将返回AR关系对象。这意味着您可以链接方法调用:

@users = User.all_except(current_user).paginate

您可以排除任意数量的用户,因为where()也接受了数组。

@users = User.all_except([1,2,3])

例如:

@users = User.all_except(User.unverified)

甚至通过其他协会:

class Post < ActiveRecord::Base
  has_many :comments
  has_many :commenters, -> { uniq }, through: :comments
end

@commenters = @post.commenters.all_except(@post.author)

请参阅API Docs中的where.not()

答案 1 :(得分:32)

@users = (current_user.blank? ? User.all : User.find(:all, :conditions => ["id != ?", current_user.id]))

答案 2 :(得分:16)

您还可以创建named_scope,例如在你的模型中:

named_scope :without_user, lambda{|user| user ? {:conditions => ["id != ?", user.id]} : {} }

并在控制器中:

def index
  @users = User.without_user(current_user).paginate
end

此范围将在使用nil调用时返回所有用户,并且在其他情况下除了在param中给出之外的所有用户。此解决方案的优点是您可以自由地将此调用与其他命名范围或will_paginate paginate方法链接。

答案 3 :(得分:7)

这是一个较短的版本:

User.all :conditions => (current_user ? ["id != ?", current_user.id] : [])

答案 4 :(得分:6)

关于GhandaL答案的一个注释 - 至少在Rails 3中,值得修改

scope :without_user, lambda{|user| user ? {:conditions => ["users.id != ?", user.id]} : {} }

(这里的主要变化是从'id!= ...'到'users.id!= ...';也是范围而不是Rails 3的named_scope)

简单地确定“用户”表的范围时,原始版本可以正常工作。将范围应用于关联(例如team.members.without_user(current_user)....)时,需要进行此更改以阐明我们用于id比较的表。我没有看到SQL错误(使用SQLite)。

对单独回答道歉......我还没有直接评论GhandaL答案的声誉。

答案 5 :(得分:2)

我使用的非常简单的解决方案

@users = User.all.where("id != ?", current_user.id)

答案 6 :(得分:1)

User.all.where(&#34; id NOT IN(?)&#34;,current_user.id)将通过异常 #<Array:0x0000000aef08f8>

的未定义方法
User.where("id NOT IN (?)", current_user.id)

答案 7 :(得分:0)

另一种简单的方法:

@users = User.all.where("id NOT IN(?)", current_user.id)

答案 8 :(得分:0)

数组会更有帮助

的ArrayID [0] = 1

的ArrayID [1] = 3

User.where.not(id:arrayID)

答案 9 :(得分:0)

User.where(:id.ne => current_user.id)

答案 10 :(得分:-5)

您正在做的是从@users数组中删除current_user。这不起作用,因为没有数组的删除方法。你可能想做的就是这个

def index
  @users = User.all
  @users - [current_user]
end

这将返回@users数组的副本,但删除了current_user对象(它首先包含在数组中。

注意:如果数组减法基于对象的精确匹配而不是内容,则此操作可能无效。但是当我尝试它时,它与字符串一起工作。请记住将current_user包含在[]中以强制它进入数组。