2015-02-20 2 views
-1

Когда я включаю его, он слева присоединяется к таблице, в которую я хочу отфильтровать, но когда я добавляю отрыв, это соединение исчезает. Есть ли способ, чтобы смешать срывать и оставил присоединиться без ручного ввода SQL для «левых присоединиться к»ActiveRecord с использованием pluck с включенными/левыми внешними соединениями

Вот мой случай:

Select u.id 
From users u 
Left join profiles p on u.id=p.id 
Left join admin_profiles a on u.id=a.uid 
Where 2 in (p.prop, a.prop, u.prop) 

Делать это просто загрузив все значения:

Users.includes(:AdminProfiles, :Profiles).where(...).map{ |a| a[:id] } 

Но когда я собираюсь вместо карты, он не остается входить в таблицы профилей.

+0

Вы действительно должны сформировать лучший вопрос, добавить примеры, ошибки, чтобы избежать попадания downvotes. –

ответ

2

Ваша проблема заключается в том, что вы используете includes, который на самом деле не выполняет соединение, вместо этого он запускает второй запрос после первого запроса для ассоциаций, в вашем случае вы хотите, чтобы они оба были фактически соединены, поэтому для этого замените includes(:something) на joins(:something), и каждая вещь должна работать нормально.

Ответ на ваш комментарий, я буду цитирует несколько частей из rails guide about active record query interface

  1. из секции Solution to N + 1 queries problem

    clients = Client.includes(:address).limit(10) 
    clients.each do |client| 
        puts client.address.postcode 
    end 
    

    выше код будет выполняться только 2 запросов, в отличии до 11 запросов в предыдущем случае:

    SELECT * FROM clients LIMIT 10 
    SELECT addresses.* FROM addresses WHERE (addresses.client_id IN (1,2,3,4,5,6,7,8,9,10)) 
    

    , как вы можете видеть, два запроса, никаких объединений вообще.

  2. В разделе Specifying Conditions on Eager Loaded Associationslink

    Даже если Active Record позволяет задать условия на нетерпеливых нагруженных ассоциаций так же, как соединения, рекомендуемый способ заключается в использовании вместо присоединяется.

    Далее приведен пример:

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

    Это создаст запрос, который содержит левое внешнее соединение, тогда как включается метод будет генерировать один с помощью INNER JOIN функцию вместо этого.

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

    Если бы не было, где состояние, это не будет генерировать нормальный набор из двух запросов.

+0

Включает левое соединение, оно не запускает другой запрос. Join делает внутреннее соединение, чтобы сделать его левым соединением, вам нужно написать инструкцию sql. Мой вопрос в порядке. – user433342

+0

Пожалуйста, ознакомьтесь с моим измененным вопросом, чтобы понять, почему мне нужны левые соединения. – user433342

+0

«Включает левое соединение, оно не запускает другой запрос» -> 'includes' пытается быть умным и делает одно в зависимости от некоторой логики. – Lloeki

 Смежные вопросы

  • Нет связанных вопросов^_^