Модель Rails, представление, контроллер и помощник:что куда?

StackOverflow https://stackoverflow.com/questions/60658

Вопрос

Какому быстрому правилу мне следует следовать в Ruby on Rails Development (или MVC в целом) относительно того, куда помещать логику?

Пожалуйста, ответьте утвердительно - С Поместите это сюда, скорее, чем Не помещайте это туда.

Это было полезно?

Решение

MVC

Контроллер:Поместите сюда код, который определяет, чего хочет пользователь, и решает, что ему дать, определяет, вошли ли они в систему, должны ли они видеть определенные данные и т. д.В конце концов, контроллер просматривает запросы и определяет, какие данные (модели) отображать и какие представления отображать.Если вы сомневаетесь, следует ли помещать код в контроллер, то, вероятно, не следует.Держите свои контроллеры тощий.

Вид:Представление должно содержать только минимальный код для отображения ваших данных (модели), оно не должно выполнять большую обработку или вычисления, оно должно отображать данные, рассчитанные (или обобщенные) с помощью модели или сгенерированные контроллером.Если вашему представлению действительно необходимо выполнить обработку, которую не может выполнить модель или контроллер, поместите код в помощник.Большое количество Ruby-кода в представлении затрудняет чтение разметки страниц.

Модель:Ваша модель должна быть там, где все ваш код, который относится к вашим данным (субъектам, составляющим ваш сайт, напримерПользователи, сообщения, учетные записи, друзья и т. д.) живет.Если коду необходимо сохранить, обновить или обобщить данные, связанные с вашими сущностями, разместите его здесь.Его можно будет повторно использовать в ваших представлениях и контроллерах.

Другие советы

Чтобы добавить к ответу Полифонического:

Помощник:функции, упрощающие создание представления.Например, если вы всегда перебираете список виджетов, чтобы отобразить их цену, поместите его в вспомогательный метод (вместе с партиалом для фактического отображения).Или, если у вас есть часть RJS, которую вы не хотите загромождать представление, поместите ее в помощник.

Шаблон MVC на самом деле касается только пользовательского интерфейса и ничего больше.Не следует помещать в контроллер какую-либо сложную бизнес-логику, поскольку он управляет представлением, но не логикой.Контроллеру следует заняться выбором правильного представления и делегировать более сложные задачи модели предметной области (модели) или бизнес-уровне.

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

Обычно я рассматриваю уровень сервиса как API моих приложений.Уровни «Мои сервисы» обычно очень близко соответствуют требованиям приложения, которое я создаю, поэтому уровень «Сервис» действует как упрощение более сложных взаимодействий, обнаруженных на нижних уровнях моего приложения, т.е.вы могли бы достичь той же цели, минуя уровни обслуживания, но вам придется использовать гораздо больше рычагов, чтобы это заработало.

Обратите внимание: здесь я говорю не о Rails, а об общем архитектурном стиле, который решает вашу конкретную проблему.

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

Нам нужны SMART-модели, THIN-контроллеры и ТУМЫЕ представления.

http://c2.com/cgi/wiki?ModelViewController

Путь Rails заключается в том, чтобы иметь худые контроллеры и толстые модели.

Поместите в контроллер все, что связано с авторизацией/контролем доступа.

Модели — это все о ваших данных.Валидация, Отношения, CRUD, Бизнес-логика

Представления предназначены для отображения ваших данных.Только отображение и получение входных данных.

Контроллеры предназначены для контроля того, какие данные передаются из вашей модели в ваше представление (и в какое представление) и из вашего представления в вашу модель.Контроллеры также могут существовать без моделей.

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

Аналогично, если вы хотите сообщить кассиру (просмотреть) что-то, то произойдет примерно то же самое, за исключением того, что второй кассир сообщит вам, принял ли менеджер вашу информацию.Также возможно, что охранник/администратор (контролер) посоветовал вам отправиться в поход, поскольку вы не были уполномочены сообщать менеджеру эту информацию.

Если расширить метафору, то в моем стереотипном и нереалистичном мире кассиры (взгляды) красивые, но пустоголовые и часто верят всему, что вы им говорите, охранники/администраторы минимально вежливы, но не очень хорошо осведомлены, но они знают, где люди должны и что делать. не следует идти, а менеджеры действительно уродливы и подлы, но знают все и могут сказать, что правда, а что нет.

Одна вещь, которая помогает правильному разделению, - это избегать анти-шаблона «передача локальных переменных из контроллера в представление».Вместо этого:

# app/controllers/foos_controller.rb:
class FoosController < ApplicationController

  def show
    @foo = Foo.find(...)
  end

end

#app/views/foos/show.html.erb:
...
<%= @foo.bar %>
...

Попробуйте переместить его в геттер, доступный в качестве вспомогательного метода:

# app/controllers/foos_controller.rb:
class FoosController < ApplicationController

  helper_method :foo

  def show
  end

  protected

  def foo
    @foo ||= Foo.find(...)
  end

end

#app/views/foos/show.html.erb:
...
<%= foo.bar %>
...

Это упрощает изменение того, что помещается в «@foo» и как оно используется.Это увеличивает разделение между контроллером и представлением, не усложняя их.

Ну, это как бы зависит от того, с чем имеет дело логика...

Часто имеет смысл добавить в модели больше элементов, оставив контроллеры небольшими.Это гарантирует, что эту логику можно легко использовать откуда угодно для доступа к данным, которые представляет ваша модель.Представления не должны содержать почти никакой логики.Так что на самом деле, в общем, вам следует стремиться сделать так, чтобы вы Не Повторялись.

Кроме того, небольшой поиск в Google дает еще несколько конкретных примеров того, что и где происходит.

Модель:требования проверки, связи данных, создание методов, обновление методов, уничтожение методов, поиск методов (обратите внимание, что у вас должны быть не только общие версии этих методов, но и если вы часто делаете что-то, например, находите людей с рыжими волосами, используя фамилия, то вам следует извлечь эту логику, чтобы все, что вам нужно было сделать, это вызвать find_redH_by_name("smith") или что-то в этом роде)

Вид:Речь должна идти только о форматировании данных, а не об их обработке.

Контроллер:Здесь происходит обработка данных.Из Интернета:«Цель контроллера — реагировать на действие, запрошенное пользователем, принимать любые параметры, установленные пользователем, обрабатывать данные, взаимодействовать с моделью, а затем передавать запрошенные данные в окончательной форме в представление».

Надеюсь, это поможет.

Говоря простым языком, как правило,Модели будут иметь все коды, связанные с таблицами, их простыми или сложными связями (представьте их как SQL-запросы, включающие несколько таблиц), манипулирование данными/переменными для получения результата с использованием бизнес-логики.

Контроллеры будет иметь код/указатели на соответствующие модели для запрошенной работы.

Взгляды примет ввод/взаимодействие пользователя и отобразит результирующий ответ.

Любое серьезное отклонение от этих значений приведет к нежелательной нагрузке на эту часть и может повлиять на общую производительность приложения.

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

дж

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top