2011-03-24 16 views

Respuesta

207

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, se podría almacenar GroupUser.arel_table en una variable o si se utiliza dentro del modelo GroupUser sí mismo, por ejemplo, en un scope, puede usar arel_table[:user_id] en lugar de GroupUser.arel_table[:user_id]

rieles de crédito 4.0 sintaxis para @jbearden's answer

+0

¿Qué tal en las asociaciones? - has_many: group_users, -> {where.not (estado: "Declined")}, a través de:: groups, foreign_key: "user_id" – ajbraus

+4

Como nota al margen, también funciona bien encadenado: 'GroupUser.where (other_condition: true) .where.not (user_id: user_id) ' –

15

Lo que tienes es una buena forma de hacerlo, creo.

27

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

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

GroupUser.where{user_id != me} 

Ni que decir tiene, que si esta es la única refactor que se va a hacer, no vale la pena utilizar una joya y me quedaría con lo que tienes. Squeel es útil en situaciones donde tienes muchas consultas complejas que interactúan con el código de Ruby.

+1

MetaWhere es genial, pero esta tarea se puede hacer sin agregar una gema. – tybro0103

+1

@ tybro0103 por supuesto, la tarea se puede hacer (y de la manera en que OP lo está haciendo está perfectamente bien), la pregunta es sobre hacerlo más elegante. Entonces, si crees que se puede hacer más elegante sin una gema, estaría muy interesado en cómo hacerlo. –

+0

La respuesta de Vikrant proporciona una solución que no incluye sql ni incluye otra gema. Pero, estoy corregido, tu respuesta es definitivamente la más amigable con los codificadores/elegante. – tybro0103

35

Carriles 4

GroupUser.where.not(user_id: me) 
6

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

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

Así, en su 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, usted no tiene que preocuparse por eso, porque los carriles se hace cargo de él para usted:

GroupUser.where(user: me) 

En los carriles 4, como se dijo por @ dr4k3, el método de consulta tiene not b een ha añadido:

GroupUser.where.not(user: me) 
17

Carriles 4:

Si desea utilizar tanto no es igual e igual, puede utilizar:

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, es posible que desee cambiar anotaciones a lo siguiente:

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

¿Qué pasa con' GroupUser.where (group_id: group_id) .where.not (user_id: user_id) '? –

+0

@EnricoCarlesso Gracias por publicar. Actualicé mi respuesta para incluir su sugerencia. Gracias. –

6

En Rails 3, no sé nada más elegante. Sin embargo, no estoy seguro si usted 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) 
Cuestiones relacionadas