Modelo de rieles encontrar donde no es igual

127

¿Cómo puedo encontrar registros en mi base de datos en condiciones no iguales? Tengo esto ahora, pero ¿hay una forma elegante de hablar con rieles?

GroupUser.where('user_id != ?',me)
Colin
fuente
Creo que lo que tienes es una buena forma de hacerlo con Rails 3.
Spyros

Respuestas:

229

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

GroupUser.where.not(user_id: me)

En Rails 3.x

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

Para acortar la longitud, puede almacenar GroupUser.arel_tableen una variable o, si se usa dentro del modelo GroupUser, por ejemplo, en a scope, puede usar en arel_table[:user_id]lugar deGroupUser.arel_table[:user_id]

Rails 4.0 crédito de sintaxis a la respuesta de @ jbearden

Vikrant Chaudhary
fuente
¿Qué pasa en las asociaciones? - has_many: group_users, -> {where.not (estado: "Rechazado")}, a través de:: groups, foreign_key: "user_id"
ajbraus
44
Como nota al margen, también funciona bien encadenado:GroupUser.where(other_condition: true).where.not(user_id: user_id)
Enrico Carlesso
38

Carriles 4

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

La única forma de hacerlo más elegante es con MetaWhere .

MetaWhere tiene un primo más nuevo que se llama Squeel que permite un código como este:

GroupUser.where{user_id != me}

No hace falta decir que si este es el único refactor que vas a hacer, no vale la pena usar una gema y me quedaría con lo que tienes. Squeel es útil en situaciones en las que tiene muchas consultas complejas que interactúan con el código Ruby.

Jakub Hampl
fuente
44
MetaWhere es genial, pero esta tarea se puede hacer sin agregar una gema.
tybro0103
1
@ tybro0103, por supuesto, la tarea se puede hacer (y, en mi opinión, la forma en que lo hace el OP está perfectamente bien), la pregunta es hacerla más elegante. Entonces, si crees que se puede hacer más elegante sin una gema, me interesaría mucho cómo hacerlo.
Jakub Hampl
La respuesta de Vikrant proporciona una solución que no involucra sql o que incluye otra gema. Pero, estoy corregido, su respuesta es definitivamente la más codificadora / elegante.
tybro0103
1
agregando una gema para lograr una tarea tan simple. Golpear a un mozzy con una bazuca
baash05 01 de
Esto es exagerado.
courtimas
23

Carriles 4:

Si desea usar ambos no iguales e iguales, puede usar:

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

Si desea utilizar una variedad de operadores (es decir >, <), en algún momento puede cambiar las anotaciones a las siguientes:

GroupUser.where("group_id > ? AND user_id != ?", group_id, user_id)
Rick Smith
fuente
¿Qué hay de GroupUser.where(group_id: group_id).where.not(user_id: user_id)?
Enrico Carlesso
@EnricoCarlesso Gracias por publicar. Actualicé mi respuesta para incluir su sugerencia. Gracias.
Rick Smith
9

Usted debe siempre incluir el nombre de la tabla en la consulta SQL cuando se trata de asociaciones.

De hecho, si otra tabla tiene la user_idcolumna y une ambas tablas, tendrá un nombre de columna ambiguo en la consulta SQL (es decir, problemas).

Entonces, en tu ejemplo:

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

O un poco más detallado:

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

Tenga en cuenta que si está utilizando un hash, no necesita preocuparse por eso porque Rails se encarga de usted:

GroupUser.where(user: me)

En Rails 4, como dijo @ dr4k3, notse ha agregado el método de consulta :

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

En Rails 3, no sé nada más elegante. Sin embargo, no estoy seguro si sabe, su condición no igual no coincide con los valores NULL (user_id). Si quieres eso, tendrás que hacer algo como esto:

GroupUser.where("user_id != ? OR user_id IS NULL", me)
Konyak
fuente