it-swarm.com.de

Rails ActiveRecord: Alle Benutzer außer dem aktuellen Benutzer suchen

Ich finde, das sollte sehr einfach sein, aber mein Gehirn hat einen Kurzschluss. Wenn ich ein Objekt habe, das den aktuellen Benutzer darstellt, und für alle Benutzer mit Ausnahme des aktuellen Benutzers abfragen möchte, wie kann ich dies tun, wobei zu berücksichtigen ist, dass der aktuelle Benutzer manchmal nil ist.

Das mache ich gerade:

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

Was mir nicht gefällt, ist, dass ich das Abfrageergebnis nachbearbeitete. Abgesehen davon, dass ich mich ein bisschen falsch fühle, glaube ich nicht, dass dies gut funktioniert, wenn ich die Abfrage umwandle, um sie mit will_paginate auszuführen. Irgendwelche Vorschläge, wie man dies mit einer Abfrage macht? Vielen Dank.

56
SingleShot

In Rails 4 können Sie Folgendes tun:

User.where.not(id: id)

Sie können es in einem Nice-Bereich einwickeln.

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

Oder verwenden Sie eine Klassenmethode, wenn Sie bevorzugen:

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

Beide Methoden geben ein AR-Beziehungsobjekt zurück. Das heißt, Sie können Methodenaufrufe verketten:

@users = User.all_except(current_user).paginate

Sie können eine beliebige Anzahl von Benutzern ausschließen, da where() auch ein Array akzeptiert.

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

Zum Beispiel:

@users = User.all_except(User.unverified)

Und auch durch andere Verbände:

class Post < ActiveRecord::Base
  has_many :comments
  has_many :commenters, -> { uniq }, through: :comments
end

@commenters = @post.commenters.all_except(@post.author)

Siehe where.not() in den API Docs .

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

Sie können auch named_scope erstellen, z. in deinem Modell:

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

und im Controller:

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

Dieser Bereich gibt alle Benutzer zurück, wenn sie mit nil aufgerufen werden, und alle Benutzer, außer in param in anderen Fällen. Der Vorteil dieser Lösung besteht darin, dass Sie diesen Aufruf mit anderen benannten Bereichen oder mit der Methode will_paginate paginate verketten können.

16
Jakub Kosiński

Hier ist eine kürzere Version:

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

Ein Hinweis zu GhandaLs Antwort - zumindest in Rails 3 ist es eine Änderung wert

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

(Die Hauptänderung hier ist von 'id! = ...' zu 'users.id! = ...'; auch Geltungsbereich anstelle von named_scope für Rails 3)

Die ursprüngliche Version funktioniert gut, wenn Sie einfach die Tabelle Benutzer verwenden. Bei der Anwendung des Gültigkeitsbereichs auf eine Zuordnung (z. B. team.members.without_user (current_user) ...) war diese Änderung erforderlich, um zu klären, welche Tabelle wir für den ID-Vergleich verwenden. Ich habe einen SQL-Fehler (mit SQLite) ohne es gesehen.

Entschuldigung für die separate Antwort ... Ich habe noch nicht den Ruf, die Antwort von GhandaL direkt zu kommentieren.

6
Steve Bourne

Sehr einfache Lösung, die ich verwendet habe

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

User.all.where ("id NOT IN (?)", Current_user.id) wird durch die Ausnahme Undefined -Methode wo für #<Array:0x0000000aef08f8>

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

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

0
Lana Kushnir

Eine andere einfache Möglichkeit, dies zu tun:

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

ein Array wäre hilfreicher

arrayID [0] = 1

arrayID [1] = 3

User.where.not (id: arrayID)

0
Asif Alam