Модель Rails, View, Controller и Helper: что и где? - PullRequest
154 голосов
/ 13 сентября 2008

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

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

Ответы [ 10 ]

168 голосов
/ 13 сентября 2008

MVC

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

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

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

34 голосов
/ 14 сентября 2008

Добавить к ответу Полифоника:

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

13 голосов
/ 13 сентября 2008

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

Domain Driven Design имеет концепцию Services, которая представляет собой место, где вы придерживаетесь логики, которой необходимо управлять множеством различных типов объектов, что обычно означает логику, которая не относится к классу Model.

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

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

11 голосов
/ 25 сентября 2013

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

Нам нужны SMART-модели, тонкие контроллеры и представления DUMB.

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

7 голосов
/ 15 сентября 2008

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

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

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

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

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

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

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

7 голосов
/ 13 сентября 2008
4 голосов
/ 15 сентября 2008

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

# 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" и как оно используется. Это увеличивает расстояние между контроллером и представлением, не усложняя их.

2 голосов
/ 13 сентября 2008

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

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

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

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

Представление: все должно быть связано с форматированием данных, а не с обработкой данных.

Контроллер: здесь идет обработка данных. Из Интернета: «Цель контроллера - ответить на запрошенное пользователем действие, принять любые параметры, которые пользователь установил, обработать данные, взаимодействовать с моделью, а затем передать запрошенные данные в окончательном виде на вид ".

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

0 голосов
/ 01 сентября 2016

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

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

Представления примет ввод / взаимодействие пользователя и отобразит полученный ответ.

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

0 голосов
/ 03 февраля 2009

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

J

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...