LEFT OUTER se une en Rails 3

Tengo el siguiente código:

@posts = Post.joins(:user).joins(:blog).select 

que está destinado a encontrar todas las publicaciones y devolverlas junto con los usuarios y blogs asociados. Sin embargo, los usuarios son opcionales, lo que significa que INNER JOIN que :joins genera no devuelve muchos registros.

¿Cómo utilizo esto para generar un LEFT OUTER JOIN lugar?

 @posts = Post.joins("LEFT OUTER JOIN users ON users.id = posts.user_id"). joins(:blog).select 

Puede hacer esto con includes como se documenta en la guía Rails :

 Post.includes(:comments).where(comments: {visible: true}) 

Resultados en:

 SELECT "posts"."id" AS t0_r0, ... "comments"."updated_at" AS t1_r5 FROM "posts" LEFT OUTER JOIN "comments" ON "comments"."post_id" = "posts"."id" WHERE (comments.visible = 1) 

Soy un gran fan de la gem squeel :

 Post.joins{user.outer}.joins{blog} 

Admite combinaciones inner y outer , así como la capacidad de especificar una clase / tipo para las relaciones polimórficas belongs_to.

Use eager_load :

 @posts = Post.eager_load(:user) 

De forma predeterminada, al pasar ActiveRecord::Base#joins una asociación con nombre, se realizará una UNIÓN INTERNA. Tendrás que pasar una cadena que represente tu UNIÓN EXTERIOR IZQUIERDA.

De la documentación :

:joins : un fragmento de SQL para combinaciones adicionales como ” LEFT JOIN comments ON comments.post_id = id ” (raramente necesario), asociaciones nombradas en el mismo formulario utilizado para la opción :include , que realizará una INNER JOIN en la tabla asociada (s), o una matriz que contiene una mezcla de ambas cadenas y asociaciones nombradas.

Si el valor es una cadena, los registros serán devueltos de solo lectura ya que tendrán atributos que no se corresponden con las columnas de la tabla. Pase :readonly => false para anular.

Hay un método left_outer_joins en activerecord. Puedes usarlo así:

 @posts = Post.left_outer_joins(:user).joins(:blog).select 

Buenas noticias, Rails 5 ahora es compatible con LEFT OUTER JOIN . Su consulta ahora se vería así:

 @posts = Post.left_outer_joins(:user, :blog) 
 class User < ActiveRecord::Base has_many :friends, :foreign_key=>"u_from",:class_name=>"Friend" end class Friend < ActiveRecord::Base belongs_to :user end friends = user.friends.where(:u_req_status=>2).joins("LEFT OUTER JOIN users ON users.u_id = friends.u_to").select("friend_id,u_from,u_to,u_first_name,u_last_name,u_email,u_fbid,u_twtid,u_picture_url,u_quote")