Rails .create() против контроллера#create

#ruby-on-rails #ruby-on-rails-3 #model #controller #action

#ruby-on-rails #ruby-on-rails-3 #Модель #контроллер #Экшен

Вопрос:

Это вопрос новичка Rails:

Когда я вызываю create() модель, обходит ли это соответствующее действие контроллера create ?

Например, это не затрагивает мои теги controller #create action:

 user.tags.create(:content => new_tag)
  

Но если я отправляю сообщение на tags#create маршрут из формы, тогда это работает просто отлично.

Я предполагал, что вызов user.tags.create вызовет действие контроллера и всегда будет запускать код в нем при создании, но, по-видимому, это происходит только во время отправки по этому маршруту.

Чего мне здесь не хватает?

Редактировать:

Есть ли способ выполнить этот вызов, чтобы убедиться, что код создания контроллера запущен? У меня есть некоторый код, чтобы найти тег по постоянной ссылке и при необходимости создать новый, иначе повторно используйте существующий. Использование model.create() не запускает ничего из этого кода. Я мог бы «делать это неправильно», хотя: P

Ответ №1:

Модель ничего не знает о контроллере, это просто объект, представляющий состояние, хранящееся в базе данных, возможно, с некоторыми дополнительными инкапсулированными поведениями. Контроллер — это объект, который отвечает на запросы, отправляемые на ваш сервер. Хотя строительные леса по умолчанию изменят вашу модель, контроллерам даже не обязательно использовать модель.

Контроллеры и модели отключены, но только логически связанные классы.

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

Комментарии:

1. Есть ли способ выполнить этот вызов, чтобы убедиться, что create код контроллера запущен? У меня есть некоторый код, чтобы найти тег по постоянной ссылке и при необходимости создать новый, иначе повторно используйте существующий. Использование model.create() не запускает ничего из этого кода.

2. Вы захотите поместить этот код в свою модель и вызвать его с контроллера и из любого другого места, где вы хотели бы иметь такое поведение. Контроллер должен вызываться rails только в ответ на запрос к вашему серверу или через ваши модульные тесты / спецификации.

3. используйте фрейм тестирования для имитации запроса POST, в противном случае используйте свой браузер. С другой стороны, может быть, этот код принадлежит модели?

Ответ №2:

Rails работает по шаблону проектирования MVC. M — это модели, которые обычно являются классами ORM. В Rails ActiveRecord является ORM по умолчанию, и каждая модель сопоставляется таблице в базе данных. Вот где должна быть суть вашей логики. Модели ничего не знают о большом мире, откуда они вызываются, например, из Интернета, веб-страницы или контроллера.

Контроллер формирует C MVC. Это конечные точки ваших веб-приложений. Каждый раз, когда URL вызывается из браузера, он заканчивается на конечной точке контроллера. Действие контроллера «создать» является конечной точкой. Этот метод чаще называют «действием». Задача действия «создать» контроллера должна заключаться в организации создания объектов, обработке и упаковке ошибок, а затем перенаправлении в другое местоположение или отправке ответа обратно с использованием представлений.

Представление формирует V MVC. Не хочу углубляться в V, поскольку это не относится к вашему вопросу, и я предполагаю, что вы это уже знаете.

Таким образом, метод «create» вашей модели, доступный с помощью ActiveRecord, значительно отличается от действия контроллера «create». Действие create в контроллере может вызывать метод create в модели как часть ее оркестровки.

Общепринятой практикой является сохранение «тощих контроллеров» и «толстых моделей». Убедитесь, что действие вашего контроллера ограничено не более чем несколькими строками (обычно 5-6 строк для действия create). Часть логики вашей программы должна быть в самой модели.

Не смотрите, что при вызове user.tags.create вызывается действие «создать» контроллера.tags.create. К контроллеру отправляются только запросы веб-браузера.

Комментарии:

1. Спасибо за подробное объяснение!

Ответ №3:

user.tags.create вызывает ActiveRecord#create метод, унаследованный от Tags , для чего TagsController#create и предоставляет нам доступный интерфейс.

ActiveRecord#create создает новый объект модели, а затем сохраняет его, ничего общего с представлением или контроллером,

Controller#create вероятно, вызывает модель create, если разрешения правильные, параметры и т.д., Но он делает это как ответ на сообщение с веб-страницы

по сути, модель и контроллер являются двумя отдельными объектами и взаимодействуют с помощью своих методов

узнайте больше о методологии MVC

Ответ №4:

Вы правы. ModelClass#create не имеет ровно никакого отношения к контроллеру.

Задача контроллера состоит в том, чтобы реагировать на ввод или «действие», выполнять любые связанные с моделью действия, которые необходимо выполнить, а затем иным образом настраивать сцену для представления (выбранного методом / действием контроллера) для отображения деталей.

На высоком уровне задачей модели является инкапсуляция данных и, в случае моделей на основе ActiveRecord, посредническая передача данных между структурами данных на основе памяти («модели») и базовым постоянным хранилищем (база данных).

Исходя из вашего редактирования, мне кажется, что вы хотите запустить свой метод Tags#create, чтобы выполнить некоторую работу, связанную с данными. Это было бы более уместно сделать в модели IMO, поскольку звучит так, как будто вы выполняете строго связанные с данными вещи и не нуждаетесь в полном «цикле MVC», связанном с вызовом метода контроллера. Можете ли вы выполнить то, что вы хотите сделать, в обратном вызове before_create для вашего ModelClass? Посмотрите здесь для получения дополнительной информации об обратных вызовах ActiveRecord (включая before_create).

Комментарии:

1. вероятно, потому, что это ничего не объясняет в том, что касается ответа на его вопрос: «да, вы были неправы», не говорит ему, «чего ему здесь не хватает», и при этом это действительно не объясняет и даже не пытается объяснить что-либо в полезном смысле, это было не от меня, но я рассмотрел это