В какой момент создается объект контроллера и сколько он живет

В Ruby on Rails объект контроллера создается на каждом HTTP-запросе и живет только в рамках обработки одного этого запроса. Это означает, что экземпляр контроллера не является долговечным — он создается, используется для выполнения логики и рендеринга, а затем уничтожается. Ниже подробно разобран весь процесс, связанный с созданием и жизненным циклом объекта контроллера.

1. Когда создается объект контроллера

Объект контроллера создается после прохождения запроса через Rack middleware и маршрутизатор (router). Весь процесс можно представить поэтапно:

  1. Клиент отправляет HTTP-запрос (например, GET /articles/5).

  2. Запрос попадает в стек Rack middleware.

  3. Middleware передает управление в маршрутизатор (ActionDispatch::Routing::RouteSet).

Маршрутизатор (routes.rb) находит подходящий маршрут:

<br/>get '/articles/:id', to: 'articles#show'
  1. Rails определяет:

    • имя контроллера (ArticlesController)

    • экшн (show)

На этом этапе создаётся объект контроллера:

<br/>controller = ArticlesController.new

Rails сам управляет этим процессом внутри фреймворка, в частности, через метод dispatch контроллера, вызываемый маршрутизатором.

2. Что происходит после создания контроллера

После создания экземпляра контроллера происходит следующая последовательность:

  • Внутри ActionController::Base запускается метод process(action_name), который:

    • устанавливает объект запроса (request) и ответа (response)

    • устанавливает параметры (params)

    • вызывает все фильтры (before_action, around_action, after_action)

    • вызывает метод контроллера (например, show)

    • формирует ответ, если он не был явно возвращён

Пример:

class ArticlesController < ApplicationController
before_action :set_article
def show
\# доступен self, @article, params и т.д.
end
private
def set_article
@article = Article.find(params\[:id\])
end
end

3. Как долго живет объект контроллера

Объект контроллера живет только в пределах одного запроса. После того как:

  • завершено выполнение экшена (show, index и т.д.)

  • сформирован и отправлен HTTP-ответ клиенту

  • выполнены after_action-фильтры (если есть)

  • завершена работа middleware и Rack

...контроллер уничтожается, и память, занимаемая его экземпляром, может быть освобождена сборщиком мусора Ruby.

Контроллер не сохраняется между запросами. Это важно, так как:

  • нельзя использовать переменные экземпляра контроллера (@something) в нескольких запросах

  • нельзя рассчитывать на сохранение состояния объекта

  • вся необходимая информация (например, id пользователя) должна храниться в сессии, куках, базе данных или передаваться в каждом запросе

4. Почему каждый запрос получает новый экземпляр контроллера

Rails придерживается принципа stateless (без состояния), как и HTTP. Это обеспечивает:

  • изоляцию между запросами: один пользователь не повлияет на обработку другого

  • безопасность: нельзя случайно "поделиться" переменной между клиентами

  • упрощение отладки и понимания кода

  • масштабируемость: приложение может обрабатывать множество запросов независимо

Таким образом, создавая новый объект контроллера каждый раз, Rails обеспечивает чистоту архитектуры и надёжность работы.

5. Особенности жизненного цикла

Объект контроллера:

  • Создается: после маршрутизации, но до выполнения экшена.

  • Инициализируется: с контекстом запроса (request, params, session, cookies, headers).

  • Используется: для вызова экшена и выполнения логики.

  • Уничтожается: после завершения формирования ответа.

Также стоит отметить, что:

  • Все instance-переменные (@article, @user, @products) живут только в рамках этого объекта.

  • После вызова экшена результат передается во View для рендеринга.

6. Пример

\# HTTP-запрос: GET /users/1
\# Внутри маршрутизатора:
UsersController.new.process(:show)
\# Что происходит:
1\. new  создается экземпляр UsersController
2\. process(:show)
\- запускается before_action
\- вызывается метод show
\- рендерится шаблон show.html.erb
3\. Ответ отправляется клиенту
4\. Объект контроллера удаляется

7. Исключения и обработка ошибок

Если в процессе выполнения контроллера возникает исключение (например, запись не найдена), то:

  • Rails вызывает middleware для обработки ошибок

  • можно определить rescue_from в контроллере

  • тем не менее, объект контроллера всё равно уничтожается после завершения обработки

class ArticlesController < ApplicationController
rescue_from ActiveRecord::RecordNotFound, with: :not_found
def show
@article = Article.find(params\[:id\])
end
def not_found
render plain: "Not found", status: 404
end
end

Жизненный цикл контроллера в Rails чётко ограничен одним запросом, что делает его надёжным, предсказуемым и изолированным компонентом MVC-архитектуры.