Я знаю, что на подобные вопросы ответили прежде - такие как:
Но у меня есть более конкретный вопрос - Как далеко должен я брать эту аксиому: сохраните свой контроллер тощим, сделайте свой образцовый жир!
Вот пример:
Например, скажем, у меня есть несколько источник данных проверки. Хорошим примером было бы число VIN - я могу проверить его против, источник данных производителей, источник данных DMV, также мои локальные базы данных - для наблюдения то, что я имею зарегистрированный. Таким образом, у меня есть модель по имени Vin и vins_controller. В модели у меня есть 5 методов:
В моем контроллере, остающемся с остальными, на шоу действия - у меня есть простой оператор выбора, который смотрит на параметрические усилители [: источник], и на основе указанного источника - назовет определенный метод проверки.
Теперь вот вопрос: я должен оставить логику, которая управляет, какой источник данных звонить в контроллер или я должен переместить ее для моделирования, и затем в контроллере просто чему-то нравится check_vin (источник, vin)?
Я должен сделать своего страдающего анорексией контроллера?
Править
Я переключаю это на официальный ответ от @jay-godse (спасибо - в то время, когда это был хороший ответ). Вещи изменились много с 2010, и этот вопрос все еще получает некоторые представления - таким образом, надо надеяться, это укажет на некоторых людей в правильном направлении и поможет им организовать свой код правильно.
Драгоценный камень новатора решает проблемы, поднятые в вопросе действительно хорошо.
Есть старая поговорка:
Умные структуры данных и тупой code работает намного лучше, чем наоборот .
Все, что вы описали, касается того, как одни данные соотносятся с другими. Это само по себе является вашим ключом к тому, что логика этих отношений, включая проверку, должна находиться на уровне модели или базы данных.
Контроллер анорексии - признак хорошо продуманных (умных?) Данных. Мой опыт подсказывает мне, что чем больше усилий вы вкладываете в разработку своих данных, тем меньше кода вам нужно написать в целом.
Контроллеры лучше всего подходят для синтаксического анализа входных данных, вызова соответствующих моделей и последующего форматирования выходных данных.
Я бы поместил логику в мою модель, особенно если я TDD'ing (а я всегда TDD, за исключением тех случаев, когда я этого не делаю). Тестирование модели обычно намного проще, чем тестирование контроллера.
Ответственность за "разбор" params
лежит на контроллере, но валидация должна производиться в модели.
Я бы сделал что-то вроде этого в контроллере:
@my_model = MyModel.new(:source => params[:source] ...)
if(@my_model.valid?)
# treat valid model here (i.e. save the model and redirect to show)
else
# treat validation error here (usually throw an error)
end
Ваш контроллер на самом деле будет просто "тощим". Для действительно "анорексичных" контроллеров вы можете взглянуть на inherited_resources или resource_this. В некоторых случаях они дадут вам контроллер из трех строк, реализующий весь стек RESTful.
Мне нравится подходить к подобным вопросам, думая об ответственности. Что в данном случае "отвечает" за проверку VIN? Модель. Контроллер просто присутствует для передачи параметров... для "управления" на основе пользовательского ввода.
Если это не совсем понятно, подумайте об этом так: где размещение этого кода вызовет наименьшие последствия, если его нужно будет использовать повторно? Скажем... если два разных действия в двух разных контроллерах должны проверить VIN, что нужно будет сделать? Если бы вы оставили этот код в контроллере, вам пришлось бы продублировать его и в новом контроллере, но если бы вы поместили его в модель, вы бы просто вызвали метод check_vin из нового контроллера, и никакого дублирования кода не потребовалось бы. Распределив обязанности там, где они имеют наибольший смысл, вы улучшили возможность повторного использования вашего кода.