我觉得这应该很简单,但我的大脑正在短路。如果我有一个表示当前用户的对象,并且想要查询除当前用户以外的所有用户,我该怎么做呢,考虑到当前用户有时可能是nil
?
这就是我现在正在做的事情:
def index
@users = User.all
@users.delete current_user
end
我不喜欢的是我正在对查询结果进行后处理。除了感觉有点不对外,如果我将查询转换为与will_paginate
一起运行,我认为这不会很好。有关如何使用查询执行此操作的任何建议?感谢。
答案 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包含在[]中以强制它进入数组。