Rails ActiveRecord: Buscar todos los usuarios excepto el usuario actual

Siento que esto debería ser muy simple, pero mi cerebro está cortocircuitando en eso. Si tengo un objeto que representa al usuario actual y deseo consultar para todos los usuarios, excepto el usuario actual, ¿cómo puedo hacerlo, teniendo en cuenta que el usuario actual a veces puede ser nil ?

Esto es lo que estoy haciendo en este momento:

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

Lo que no me gusta es que estoy haciendo post-procesamiento en el resultado de la consulta. Además de sentirme un poco mal, no creo que esto funcione bien si convierto la consulta para que se ejecute con will_paginate . ¿Alguna sugerencia de cómo hacer esto con una consulta? Gracias.

Es posible hacer lo siguiente en Rails 4:

 User.where.not(id: id) 

Puedes envolverlo en un buen scope.

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

O use un método de clase si lo prefiere:

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

Ambos métodos devolverán un objeto de relación AR. Esto significa que puede encadenar llamadas de método:

 @users = User.all_except(current_user).paginate 

Puede excluir cualquier número de usuarios porque where() también acepta una matriz.

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

Por ejemplo:

 @users = User.all_except(User.unverified) 

E incluso a través de otras asociaciones:

 class Post < ActiveRecord::Base has_many :comments has_many :commenters, -> { uniq }, through: :comments end @commenters = @post.commenters.all_except(@post.author) 

Ver where.not() en los API Docs .

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

También puede crear named_scope, por ejemplo en su modelo:

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

y en el controlador:

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

Este ámbito devolverá a todos los usuarios cuando se invoque con nil y todos los usuarios excepto en el caso de param en otro caso. La ventaja de esta solución es que puede encadenar esta llamada con otros ámbitos nombrados o con el método will_paginate de paginate.

Aquí hay una versión más corta:

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

Una nota sobre la respuesta de GhandaL: al menos en Rails 3, vale la pena modificarlo

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

(el cambio principal aquí es de ‘id! = …’ a ‘users.id! = …’; también scope en lugar de named_scope para Rails 3)

La versión original funciona bien cuando simplemente se analiza la tabla Usuarios. Al aplicar el scope a una asociación (por ejemplo, team.members.without_user (current_user) ….), este cambio fue necesario para aclarar qué tabla estamos utilizando para la comparación de id. Vi un error de SQL (usando SQLite) sin él.

Disculpas por la respuesta por separado … todavía no tengo la reputación de comentar directamente la respuesta de GhandaL.

Solución muy fácil que utilicé

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

Otra forma fácil de hacerlo:

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

User.all.where (“id NOT IN (?)”, Current_user.id) a través del método de excepción indefinido donde para #

 User.where("id NOT IN (?)", current_user.id) 

una matriz sería más útil

arrayID [0] = 1

arrayID [1] = 3

User.where.not (id: arrayID)

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

Lo que está haciendo es eliminar el usuario_actual de la matriz @users. Esto no funcionará ya que no hay un método de eliminación para las matrices. Lo que probablemente quieras hacer es esto

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

Esto devolverá una copia de la matriz @users, pero con el objeto current_user eliminado (en primer lugar, estaba contenido en la matriz).

Nota: Esto puede no funcionar si la resta de matriz se basa en coincidencias exactas de objetos y no en el contenido. Pero funcionó con cuerdas cuando lo probé. Recuerde incluir current_user en [] para forzarlo a una matriz.