Question
I feel this should be very simple but my brain is short-circuiting on it. If I
have an object representing the current user, and want to query for all users
except the current user, how can I do this, taking into account that the
current user can sometimes be nil
?
This is what I am doing right now:
def index
@users = User.all
@users.delete current_user
end
What I don't like is that I am doing post-processing on the query result.
Besides feeling a little wrong, I don't think this will work nicely if I
convert the query over to be run with will_paginate
. Any suggestions for how
to do this with a query? Thanks.
Answer
It is possible to do the following in Rails 4 and up:
User.where.not(id: id)
You can wrap it in a nice scope.
scope :all_except, ->(user) { where.not(id: user) }
@users = User.all_except(current_user)
Or use a class method if you prefer:
def self.all_except(user)
where.not(id: user)
end
Both methods will return an AR relation object. This means you can chain method calls:
@users = User.all_except(current_user).paginate
You can exclude any number of users because
[where()
](http://edgeguides.rubyonrails.org/active_record_querying.html#not-
conditions) also accepts an array.
@users = User.all_except([1,2,3])
For example:
@users = User.all_except(User.unverified)
And even through other associations:
class Post < ActiveRecord::Base
has_many :comments
has_many :commenters, -> { uniq }, through: :comments
end
@commenters = @post.commenters.all_except(@post.author)
See where.not()
in the [API
Docs](http://edgeguides.rubyonrails.org/active_record_querying.html#not-
conditions).