Rails Model trova dove non è uguale


127

Come posso trovare i record nel mio database a una condizione non uguale? Ora ho questo, ma esiste un modo stravagante per farlo?

GroupUser.where('user_id != ?',me)

Penso che sia un buon modo per farlo di Rails 3.
Spyros,

Risposte:


229

In Rails 4.x (vedi 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))

Per ridurre la lunghezza, è possibile memorizzare GroupUser.arel_tablein una variabile o se si utilizza all'interno del modello GroupUserstesso, ad es. In a scope, è possibile utilizzare arel_table[:user_id]anzichéGroupUser.arel_table[:user_id]

Credito sintassi Rails 4.0 alla risposta di @ jbearden


Che dire delle associazioni? - has_many: group_users, -> {where.not (status: "Declined")}, attraverso:: groups, foreign_key: "
user_id

4
Come nota a margine, funziona anche incatenato:GroupUser.where(other_condition: true).where.not(user_id: user_id)
Enrico Carlesso,


26

L'unico modo per renderlo più elaborato è con MetaWhere .

MetaWhere ha un cugino più recente che si chiama Squeel che consente un codice come questo:

GroupUser.where{user_id != me}

Inutile dire che se questo è l'unico refattore che stai per creare, non vale la pena usare una gemma e rimarrei solo con quello che hai. Squeel è utile in situazioni in cui hai molte query complesse che interagiscono con il codice Ruby.


4
MetaWhere è fantastico, ma questa attività può essere eseguita senza aggiungere una gemma.
tybro0103,

1
@ tybro0103 ovviamente il compito può essere svolto (e imho il modo in cui l'OP lo sta facendo perfettamente bene), la domanda è di farlo più elaborato. Quindi se pensi che possa essere fatto più elaborato senza una gemma, sarei molto interessato a come farlo.
Jakub Hampl,

La risposta di Vikrant fornisce una soluzione che non coinvolge sql o include un altro gioiello. Ma, mi correggo, la tua risposta è sicuramente la più adatta ai programmatori / alla fantasia.
tybro0103,

1
aggiungendo una gemma per realizzare un compito così semplice. Colpire un mozzy con un bazooka
baash05

Questo è eccessivo.
cortei

23

Rotaie 4:

Se si desidera utilizzare entrambi non uguali e uguali, è possibile utilizzare:

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

Se si desidera utilizzare una varietà di operatori (ad es. >, <), Ad un certo punto è possibile passare da una notazione all'altra:

GroupUser.where("group_id > ? AND user_id != ?", group_id, user_id)

Che dire GroupUser.where(group_id: group_id).where.not(user_id: user_id)?
Enrico Carlesso,

@EnricoCarlesso Grazie per la pubblicazione. Ho aggiornato la mia risposta per includere il tuo suggerimento. Grazie.
Rick Smith,

9

Dovresti sempre includere il nome della tabella nella query SQL quando hai a che fare con le associazioni.

Infatti se un'altra tabella ha la user_idcolonna e si uniscono entrambe le tabelle, si avrà un nome di colonna ambiguo nella query SQL (ovvero problemi).

Quindi, nel tuo esempio:

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

O un po 'più prolisso:

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

Nota che se stai usando un hash, non devi preoccuparti perché Rails se ne prende cura per te:

GroupUser.where(user: me)

In Rails 4, come detto da @ dr4k3, notè stato aggiunto il metodo di query :

GroupUser.where.not(user: me)

6

In Rails 3, non so nulla di più elaborato. Tuttavia, non sono sicuro che tu sia a conoscenza, la tua condizione non uguale non corrisponde ai valori NULL (user_id). Se lo desideri, dovrai fare qualcosa del genere:

GroupUser.where("user_id != ? OR user_id IS NULL", me)
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.