LEFT OUTER присоединяется к Rails 3 - PullRequest
85 голосов
/ 14 июля 2010

У меня есть следующий код:

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

, который предназначен для поиска всех сообщений и их возвращения, а также для связанных пользователей и блогов. Однако, пользователи необязательны, что означает, что INNER JOIN, который генерирует :joins, не возвращает много записей.

Как я могу использовать это для генерации LEFT OUTER JOIN вместо?

Ответы [ 8 ]

111 голосов
/ 14 июля 2010
@posts = Post.joins("LEFT OUTER JOIN users ON users.id = posts.user_id").
              joins(:blog).select
75 голосов
/ 12 октября 2012

Вы можете сделать это с помощью includes , как описано в руководстве по Rails :

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

Результат:

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)
11 голосов
/ 02 ноября 2013

Я большой поклонник камня squeel :

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

Он поддерживает соединения inner и outer, а также возможность указывать класс/ тип для полиморфных отношений владение_то

10 голосов
/ 14 ноября 2014

Использование eager_load:

@posts = Post.eager_load(:user)
8 голосов
/ 14 июля 2010

По умолчанию, когда вы передаете ActiveRecord::Base#joins именованную ассоциацию, она выполняет ВНУТРЕННЕЕ СОЕДИНЕНИЕ.Вам нужно будет передать строку, представляющую ваше левое внешнее соединение.

Из документации :

:joins - либо фрагмент SQL для дополнительных объединенийкак "LEFT JOIN comments ON comments.post_id = id" (редко требуется), именованные ассоциации в той же форме, что и для опции :include, которая будет выполнять INNER JOIN для связанных таблиц, или массив, содержащий смесь как строк, так и именованныхассоциации.

Если значение является строкой, то записи будут возвращаться только для чтения, поскольку они будут иметь атрибуты, которые не соответствуют столбцам таблицы.Передайте :readonly => false для переопределения.

7 голосов
/ 22 июня 2016

В activerecord есть метод left_outer_joins . Вы можете использовать это так:

@posts = Post.left_outer_joins(:user).joins(:blog).select
4 голосов
/ 22 сентября 2016

Хорошие новости, Rails 5 теперь поддерживает LEFT OUTER JOIN.Ваш запрос теперь будет выглядеть так:

@posts = Post.left_outer_joins(:user, :blog)
0 голосов
/ 02 июля 2014
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")
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...