Метод includes
был разработан для решения задачи N + 1 запроса.Например, если у вас есть модель:
class MyModel < ApplicationRecord
has_many :translations
end
, то этот код
MyModel.limit(50).each do |model|
model.translations.each do |translation|
# ...
end
end
генерирует 51 запрос к вашей базе данных: один запрос на выборку 50 записей из таблицы my_models
и50 запросов для получения translations
для каждой из этих моделей.Это сильно влияет на производительность приложения.
Чтобы исправить это, код можно переписать так:
MyModel.includes(:translations).limit(50).each do |model|
...
С includes
Rails генерирует только 2 SQL-запроса.Первый получает 50 my_models
записей, а второй запрос translations
для этих my_models
.
Имея default_scope -> { includes(:translations) }
, вы просто пропустите запись includes(:translations)
в ситуациях, описанных выше.Даже если вы напишите
MyModel.limit(50).each do |model|
...
Rails сделает 2 запроса, поскольку переводы включены в область действия по умолчанию.
Мне нужно добавить, что default_scope имеет некоторые неочевидные ловушкии не рекомендуется некоторыми разработчиками.