В чем разница между «включает» и «соединения» в запросе ActiveRecord? - PullRequest
19 голосов
/ 01 февраля 2011

В чем разница между " включает " и " объединения " в запросе ActiveRecord? Кто-нибудь может объяснить мне следующие две связанные модели?

class Car < ActiveRecord::Base
  belongs_to :store
end

class Store < ActiveRecord::Base
  belongs_to :owner
  has_one :car
end

Ответы [ 5 ]

35 голосов
/ 27 сентября 2013
stores = Store.joins(:car)

Это вернет все магазины, для которых есть автомобиль.stores[0].car приведет к другому запросу.

stores = Store.includes(:car)

Это вернет все магазины, машины или нет машины.stores[0].car приведет , а не к другому запросу.

stores = Store.includes(:car).joins(:car)

Это вернет все магазины с машиной.stores[0].car будет , а не приведет к другому запросу.Я бы не рекомендовал это для has_many отношений, но он прекрасно работает для has_one.

23 голосов
/ 01 февраля 2011

:joins объединяет таблицы в sql, :includes активно загружает ассоциации, чтобы избежать проблемы n + 1 (когда один запрос выполняется для извлечения записи, а затем один для каждой ассоциации, которая загружена).

Я предлагаю вам прочитать их разделы в Rails Guides , чтобы получить больше информации.

4 голосов
/ 19 июня 2012

: объединения возвращают объекты только для чтения,: включает не

: для объединения используется внутреннее соединение, для: используется внешнее соединение.

Основная причина: включает в себя стремительную загрузку, чтобы избежать проблемы N + 1 загрузки атрибутов каждого объекта с использованием отдельного запроса.

3 голосов
/ 11 апреля 2012

Объединения будут просто объединять таблицы и возвращать выбранные поля.если вы вызовете ассоциации в результате запроса на присоединение, он снова запустит запросы к базе данных

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

Подробное объяснение с примерами из этой статьи вы можете найти: Советы и рекомендации по ассоциациям активной записи .

0 голосов
/ 07 декабря 2017

TL;DR

Регистрация:

a.joins(:b).to_sql
=> "SELECT \"a\".* FROM \"a\" INNER JOIN \"b\" ON \"b\".\"id\" = \"a\".\"b_id\""

Включает в себя:

a.includes(:b).to_sql
=> "SELECT \"a\".* FROM \"a\"

Оба:

a.includes(:b).joins(:b).to_sql
=> "SELECT \"a\".\"id\" AS t0_r0, \"a\".\"a_field_1\" AS t0_r1, \"a\".\"a_field_2\" AS t0_r2, \"a\".\"a_field_3\" AS t0_r3, \"b\".\"a_field_1\" AS t1_r1, \"b\".\"a_field_2\" AS t1_r2, \"b\".\"a_field_3\" AS t1_r3 FROM \"a\" INNER JOIN \"b\" ON \"b\".\"id\" = \"a\".\"plan_id\""
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...