В стандартной обработке Rails после выбора маршрута создаётся экземпляр контроллера для конкретного запроса, затем выполняются callbacks и action и формируется ответ. Следующий запрос получает другой экземпляр. Завершение ответа не означает немедленного уничтожения объекта: память освобождает GC, когда объект становится недостижим. Состояние между запросами хранят не в переменных экземпляра контроллера.
Когда в Rails создаётся объект контроллера и сколько он живёт?
Экземпляр контроллера на запрос, его переменные и отличие завершения обработки от фактической сборки мусора.
Короткий ответ
Что ответить на собеседовании
Подробный разбор
Ответ с пояснениями
Для запроса, который маршрутизирован в controller action, Rails создаёт новый экземпляр соответствующего класса контроллера. Упрощённая последовательность: маршрутизация → экземпляр → фильтры и action → подготовка ответа. Запрос, завершённый раньше в middleware, может вообще не дойти до контроллера. Создание через new.dispatch(...) видно в реализации ActionController::Metal.
class ProfilesController < ApplicationController
def show
@profile = current_user.profile
end
end
Здесь предполагается, что аутентификация уже выполнена. @profile относится к экземпляру, обрабатывающему текущий запрос, и может использоваться его представлением. Другой запрос создаст свой объект контроллера и свою переменную @profile.
Однако фраза «Rails уничтожает контроллер сразу после отправки ответа» неточна. Объект может стать доступен для сборки мусора после потери всех ссылок, но точный момент освобождения памяти выбирает GC. При потоковой выдаче ответа, callbacks или сохранённых внешних ссылках фактическая жизнь связанных объектов может быть дольше основного action.
Для данных между запросами используют подходящее хранилище: сессию, базу, кеш. Переменные класса и глобальное состояние не становятся изолированными лишь потому, что экземпляры контроллеров разные; в многопоточном сервере их совместное изменение требует особого внимания.
В фоновые задачи передают идентификаторы и необходимые значения, а не весь контроллер с запросом и ответом. Это уменьшает риск удерживать лишние объекты и смешивать жизненный цикл HTTP-запроса с длительной работой.