Rails ActiveRecord: Trouver tous les utilisateurs sauf utilisateur actuel

Je pense que cela devrait être très simple mais mon cerveau est en court-circuit. Si j’ai un object représentant l’utilisateur actuel et que je souhaite interroger tous les utilisateurs, à l’exception de l’utilisateur actuel, comment puis-je le faire, en tenant compte du fait que l’utilisateur actuel peut parfois être nil ?

C’est ce que je fais maintenant:

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

Ce que je n’aime pas, c’est que je fais du post-traitement sur le résultat de la requête. En plus de me sentir un peu mal, je ne pense pas que cela fonctionnera bien si je convertis la requête pour être exécutée avec will_paginate . Des suggestions pour faire cela avec une requête? Merci.

Il est possible de faire les choses suivantes dans Rails 4:

 User.where.not(id: id) 

Vous pouvez l’envelopper dans une belle scope.

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

Ou utilisez une méthode de classe si vous préférez:

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

Les deux méthodes renverront un object de relation AR. Cela signifie que vous pouvez enchaîner les appels de méthode:

 @users = User.all_except(current_user).paginate 

Vous pouvez exclure un nombre quelconque d’utilisateurs car where() accepte également un tableau.

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

Par exemple:

 @users = User.all_except(User.unverified) 

Et même à travers d’autres associations:

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

Voir where.not() dans l’ API Docs .

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

Vous pouvez également créer named_scope, par exemple dans votre modèle:

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

et dans le contrôleur:

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

Cette scope renverra tous les utilisateurs lorsqu’ils seront appelés avec nil et tous les utilisateurs, sauf dans le cas contraire. L’avantage de cette solution est que vous êtes libre de chaîner cet appel avec d’autres scopes nommées ou une méthode de pagination will_paginate.

Voici une version plus courte:

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

Une note sur la réponse de GhandaL – au moins dans Rails 3, cela vaut la peine de modifier

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

(le changement primaire ici est de ‘id! = …’ à ‘users.id! = …’; aussi la scope au lieu de named_scope pour Rails 3)

La version d’origine fonctionne correctement lorsque vous définissez simplement la scope de la table Users. Lors de l’application de la scope à une association (par exemple team.members.without_user (current_user) ….), cette modification était nécessaire pour clarifier la table que nous utilisons pour la comparaison des identifiants. J’ai vu une erreur SQL (en utilisant SQLite) sans elle.

Toutes mes excuses pour la réponse séparée … Je n’ai pas encore la réputation de commenter directement la réponse de GhandaL.

Solution très facile j’ai utilisé

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

Un autre moyen facile de le faire:

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

User.all.where (“id NOT IN (?)”, Current_user.id) utilisera la méthode exception non définie où pour #

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

un tableau serait plus utile

arrayID [0] = 1

arrayID [1] = 3

User.where.not (id: arrayID)

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

Ce que vous faites consiste à supprimer le current_user de @users Array. Cela ne fonctionnera pas car il n’y a pas de méthode de suppression pour les tableaux. Ce que vous voulez probablement faire c’est ceci

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

Cela retournera une copie du tableau @users, mais avec l’object current_user supprimé (il était contenu dans le tableau en premier lieu.

Remarque: Cela peut ne pas fonctionner si la soustraction de tableau est basée sur des correspondances exactes d’objects et non sur le contenu. Mais cela a fonctionné avec des cordes quand je l’ai essayé. N’oubliez pas de placer current_user dans [] pour le forcer dans un tableau.