Schienenmodell finden wo nicht gleich

127

Wie kann ich Datensätze in meiner Datenbank unter nicht gleichen Bedingungen finden? Ich habe das jetzt, aber gibt es eine ausgefallene Art, es zu tun?

GroupUser.where('user_id != ?',me)
Colin
quelle
Was Sie haben, ist so ziemlich eine gute Rails 3-Methode, denke ich.
Spyros

Antworten:

228

In Rails 4.x (Siehe http://edgeguides.rubyonrails.org/active_record_querying.html#not-conditions )

GroupUser.where.not(user_id: me)

In Rails 3.x.

GroupUser.where(GroupUser.arel_table[:user_id].not_eq(me))

Um die Länge zu verkürzen, können Sie GroupUser.arel_tablein einer Variablen speichern oder bei Verwendung innerhalb des Modells GroupUserselbst, z. B. in a scope, arel_table[:user_id]anstelle von verwendenGroupUser.arel_table[:user_id]

Rails 4.0-Syntax wird der Antwort von @ jbearden gutgeschrieben

Vikrant Chaudhary
quelle
Was ist mit in Vereinen? - has_many: group_users, -> {where.not (status: "Declined")}, through :: groups, Foreign_key: "user_id"
Ajbraus
4
Als Randnotiz funktioniert es auch gut verkettet:GroupUser.where(other_condition: true).where.not(user_id: user_id)
Enrico Carlesso
38

Schienen 4

GroupUser.where.not(user_id: me)
jbearden
quelle
26

Die einzige Möglichkeit, es schicker zu machen, ist mit MetaWhere .

MetaWhere hat einen neueren Cousin namens Squeel, der Code wie diesen zulässt:

GroupUser.where{user_id != me}

Es versteht sich von selbst, dass es sich nicht lohnt, einen Edelstein zu verwenden, wenn dies der einzige Refaktor ist, den Sie herstellen werden, und ich würde einfach bei dem bleiben, was Sie haben. Squeel ist nützlich in Situationen, in denen viele komplexe Abfragen mit Ruby-Code interagieren.

Jakub Hampl
quelle
4
MetaWhere ist großartig, aber diese Aufgabe kann ohne Hinzufügen eines Edelsteins ausgeführt werden.
tybro0103
1
@ tybro0103 Natürlich kann die Aufgabe erledigt werden (und imho ist die Art und Weise, wie das OP es macht, vollkommen in Ordnung), die Frage ist, ob man es schicker machen soll. Wenn Sie also glauben, dass es ohne Edelstein schicker gemacht werden kann, würde mich sehr interessieren, wie das geht.
Jakub Hampl
Vikrants Antwort liefert eine Lösung, die weder SQL noch ein anderes Juwel beinhaltet. Aber ich stehe korrigiert da, Ihre Antwort ist definitiv die kodiererfreundlichste / ausgefallenste.
tybro0103
1
Hinzufügen eines Edelsteins, um eine so einfache Aufgabe zu erfüllen. Schlagen eines Mozzy mit einer Panzerfaust
baash05
Das ist übertrieben.
Courtsimas
22

Schienen 4:

Wenn Sie sowohl ungleich als auch gleich verwenden möchten , können Sie Folgendes verwenden:

user_id = 4
group_id = 27
GroupUser.where(group_id: group_id).where.not(user_id: user_id)

(. Das heißt , wenn Sie eine Vielzahl von Operatoren verwenden möchten >, <), an einem gewissen Punkt können Sie Notationen der folgenden wechseln:

GroupUser.where("group_id > ? AND user_id != ?", group_id, user_id)
Rick Smith
quelle
Was ist mit GroupUser.where(group_id: group_id).where.not(user_id: user_id)?
Enrico Carlesso
@EnricoCarlesso Danke fürs posten. Ich habe meine Antwort aktualisiert, um Ihren Vorschlag aufzunehmen. Vielen Dank.
Rick Smith
9

Sie sollten den Tabellennamen immer in die SQL-Abfrage aufnehmen, wenn Sie sich mit Zuordnungen befassen.

Wenn eine andere Tabelle die user_idSpalte enthält und Sie beide Tabellen verbinden, haben Sie in der SQL-Abfrage einen mehrdeutigen Spaltennamen (dh Probleme).

Also, in Ihrem Beispiel:

GroupUser.where("groups_users.user_id != ?", me)

Oder etwas ausführlicher:

GroupUser.where("#{table_name}.user_id IS NOT ?", me)

Beachten Sie, dass Sie sich darüber keine Gedanken machen müssen, wenn Sie einen Hash verwenden, da Rails dies für Sie erledigt:

GroupUser.where(user: me)

In Rails 4 wurde, wie von @ dr4k3 angegeben, die Abfragemethode nothinzugefügt:

GroupUser.where.not(user: me)
Damien
quelle
6

In Rails 3 kenne ich nichts ausgefalleneres. Ich bin mir jedoch nicht sicher, ob Ihre ungleiche Bedingung nicht mit (user_id) NULL-Werten übereinstimmt. Wenn Sie das wollen, müssen Sie so etwas tun:

GroupUser.where("user_id != ? OR user_id IS NULL", me)
konyak
quelle