Encontré un problema extraño con las consultas de Rails 4 Active Record donde la tabla de inclusión no se une si uso una función de PostgreSQL en el pedido. Esta misma consulta funciona bien si elimino la función PostgreSQL.
Esto funciona bien...
Widget.includes(:sprocket).order("sprockets.name").allEsto falla porque la relación de inclusión no está unida...
Widget.includes(:sprocket).order("lower(sprockets.name)").allObserve que lo único diferente es el inferior (sprockets.name).
Sé que puedo agregar referencias como esta...
Widget.includes(:sprocket).references(:sprockets).order("lower(sprockets.name)").allEso funcionará, pero entonces, ¿cuál es el propósito de incluir?
Descubrí que reemplazar las inclusiones con la carga ansiosa también funciona, pero nuevamente, ¿cuál es el propósito de las inclusiones entonces?
Widget.eager_load(:sprocket).order("lower(sprockets.name)").allEn Rails 3, solo usar include funciona bien. Supongo que tengo mucho código para cambiar, pero ¿solo espero que haya una solución más fácil?
Gracias
Suponga que necesita obtener el nombre de usuario de las primeras cinco publicaciones. Rápidamente escribes la consulta a continuación y te vas a disfrutar de tu fin de semana.
posts = Post.limit(5) posts.each do |post| puts post.user.name endBien. Pero veamos las consultas.
Post Load (0.5ms) SELECT `posts`.* FROM `posts` LIMIT 5 User Load (0.3ms) SELECT `users`.* FROM `users` WHERE `users`.`id` = 1 LIMIT 1 User Load (0.3ms) SELECT `users`.* FROM `users` WHERE `users`.`id` = 1 LIMIT 1 User Load (0.3ms) SELECT `users`.* FROM `users` WHERE `users`.`id` = 2 LIMIT 1 User Load (0.3ms) SELECT `users`.* FROM `users` WHERE `users`.`id` = 2 LIMIT 1 User Load (0.3ms) SELECT `users`.* FROM `users` WHERE `users`.`id` = 1 LIMIT 1 1 query para obtener todas las posts y 1 query para obtener users para cada publicación da como resultado un total de 6 queries . Consulte la solución a continuación que hace lo mismo, solo en 2 queries :
posts = Post.includes(:user).limit(5) posts.each do |post| puts post.user.name end ##### Post Load (0.3ms) SELECT `posts`.* FROM `posts` LIMIT 5 User Load (0.3ms) SELECT `users`.* FROM `users` WHERE `users`.`id` IN (1, 2) Hay una pequeña diferencia. Agregue includes(:posts) a su consulta y problema resuelto. Rápido, agradable y fácil.
Pero no solo agregue includes en su consulta sin entenderlo correctamente. El uso de includes con joins puede dar lugar a uniones cruzadas según la situación, y no es necesario en la mayoría de los casos.
Si desea agregar condiciones a sus modelos incluidos, deberá hacer referencia a ellos explícitamente . Por ejemplo:
User.includes(:posts).where('posts.name = ?', 'example')Lanzará un error, pero esto funcionará:
User.includes(:posts).where('posts.name = ?', 'example').references(:posts) Tenga en cuenta que includes obras con association names mientras que las references necesitan the actual table name .