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)

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


¿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


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.


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)

¿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)

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)
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.