Je pense que cela devrait être très simple mais mon cerveau court-circuite dessus. Si j'ai un objet représentant l'utilisateur actuel et que je souhaite interroger tous les utilisateurs à l'exception de l'utilisateur actuel, comment puis-je procéder, en tenant compte du fait que l'utilisateur actuel peut parfois être nil
?
Voici ce que je fais en ce moment:
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 dans l'erreur, je ne pense pas que cela fonctionnera bien si je convertis la requête pour qu'elle soit exécutée avec will_paginate
. Des suggestions sur la façon de procéder avec une requête? Merci.
Il est possible de faire ce qui suit dans Rails 4:
User.where.not(id: id)
Vous pouvez l'envelopper dans un cadre de Nice.
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 objet de relation AR. Cela signifie que vous pouvez chaîner des appels de méthode:
@users = User.all_except(current_user).paginate
Vous pouvez exclure n'importe quel nombre 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 Documents API .
@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 portée retournera tous les utilisateurs lorsqu'elle sera appelée avec nil et tous les utilisateurs, sauf donnée dans param dans les autres cas. L'avantage de cette solution est que vous êtes libre de chaîner cet appel avec d'autres scopes nommés ou avec la méthode will_paginate paginate.
Voici une version plus courte:
User.all :conditions => (current_user ? ["id != ?", current_user.id] : [])
Une note sur la réponse de GhandaL - du moins dans Rails 3, il convient de le modifier pour
scope :without_user, lambda{|user| user ? {:conditions => ["users.id != ?", user.id]} : {} }
(Le changement principal ici est de 'id! = ...' à 'users.id! = ...'; également à la place de named_scope pour Rails 3)
La version originale fonctionne correctement lorsque vous parcourez simplement la table Users. Lors de l'application de l'étendue à une association (par exemple, team.members.without_user (current_user) ...), cette modification était nécessaire pour préciser la table utilisée pour la comparaison d'identifiant. 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)
User.all.where ("id NOT IN (?)", Current_user.id) passera par l'exception Méthode undefined où pour #<Array:0x0000000aef08f8>
User.where("id NOT IN (?)", current_user.id)
User.where (: id.ne => current_user.id)
Un autre moyen facile de le faire:
@users = User.all.where("id NOT IN(?)", current_user.id)
un tableau serait plus utile
arrayID [0] = 1
arrayID [1] = 3
User.where.not (id: arrayID)