2012-04-30 9 views
19

Tengo un modelo de usuario y el usuario tiene una relación que es has_ ​​many pets. Quiero poder escribir una consulta ActiveRecord donde pueda seleccionar todos los usuarios con una mascota que no tenga una mascota.nombre de "esponjoso"Ruby on Rails Consulta de ActiveRecord con una combinación

¿Cuál es la forma más eficiente de escribir esto usando ActiveRecord? Uso de SQL recta se vería algo como lo siguiente:

select id from users INNER JOIN pets ON u.id = pets.user_id WHERE pets.name != "fluffy"

Respuesta

37

esto debería funcionar:

User.joins(:pets).where("pets.name != 'fluffy'") 

También es posible que desee leer el following part (en joins) en las directrices oficiales de RoR.

+2

Por favor, corríjanme si me equivoco, pero ¿no sería '(User.joins: animales) ...' - singular - para el parámetro de símbolo? – jeffdill2

+2

@ jeffdill2 Eso depende de cómo se define la asociación. Si el usuario 'has_one: pet', por ejemplo, estaría en lo cierto. –

+0

@MikeC ah, a la derecha. – jeffdill2

14

La forma más limpia y sin vulnerabilidad de inyección SQL es el uso de parámetros de consulta:

User.joins(:pets).where("pets.name != ?", "fluffy") 

Algunos controladores de base de datos utilizarán declaraciones preparadas para arriba para reutilización del plan de consulta de base de datos. En tal caso, la base de datos no tiene que volver a analizar la consulta cuando solo varía el valor de param.

24

En los carriles 4 se puede hacer esto aún más claro:

User.joins(:pets).where.not(pets: { name: 'fluffy' })