85 votes

LEFT OUTER joints dans Rails 3

Je possède le code suivant :

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

ce qui est censé trouver tous les articles et les retourner ainsi que les utilisateurs et les blogs associés. Cependant, les utilisateurs sont facultatifs, ce qui signifie que l' INNER JOIN que :joins génère ne retourne pas beaucoup d'enregistrements.

Comment puis-je utiliser ceci pour générer un LEFT OUTER JOIN à la place ?

111voto

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

75voto

WuTangTan Points 718

Vous pouvez le faire avec includes comme documenté dans le guide Rails:

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

Résultats :

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)

11voto

Jimbo Points 3751

Je suis un grand fan du gem squeel:

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

Il prend en charge à la fois les jointures inner et outer, ainsi que la possibilité de spécifier une classe/ de type pour les relations polymorphiques belongs_to.

8voto

DBA Points 278

Par défaut, lorsque vous passez ActiveRecord::Base#joins une association nommée, il effectuera une jointure INTERNE. Vous devrez passer une chaîne représentant votre JOINTURE GAUCHE.

À partir de la documentation:

:joins - Soit un fragment SQL pour des jointures supplémentaires comme "LEFT JOIN comments ON comments.post_id = id" (rarement nécessaire), des associations nommées dans la même forme utilisée pour l'option :include, qui effectuera un INNER JOIN sur la/les table(s) associée(s), ou un tableau contenant un mélange de chaînes et d'associations nommées.

Si la valeur est une chaîne, alors les enregistrements seront renvoyés en lecture seule car ils auront des attributs qui ne correspondent pas aux colonnes de la table. Passez :readonly => false pour outrepasser.

0voto

Jigar Bhatt Points 170
class Utilisateur < ActiveRecord::Base
     a_beaucoup :amis, :foreign_key=>"u_from",:class_name=>"Ami"
end

class Ami < ActiveRecord::Base
     appartient_a :utilisateur
end

amis = utilisateur.amis.where(:u_req_status=>2).joins("LEFT OUTER JOIN users ON users.u_id = amis.u_to").select("ami_id,u_from,u_to,u_first_name,u_last_name,u_email,u_fbid,u_twtid,u_picture_url,u_quote")

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X