MVC и валидация

vanicon

Новичок
Всем привет.
Недавно познакомился с mvc парадигмой, посмотрел разные фреймворки...
И вроде бы все понятно, но все таки есть несколько разногласий по поводу валидации данных,
в модели или в контролллере..
Я считаю что модель должна валидировать данные, но только те которые относятся к ней...
То есть давайте рассмотрим на примере модели пользователя,
у этой модели есть свойства (логин, мыло, пароль, и тд), так вот эти вот свойства и должна уметь валидировать эта модель.
Но как быть если появилась необходимость сделать проверку капчи на странице регистрации,
то где эту проверку осуществлять?
Смотрел как в других фреймворках создаются, специальные сущности типа форма регистрации, и туда это правило уже можно было запихнуть, но на странице регистрации нужно выводить все сообщения об ошибках, а как я уже вышел писал получается у нас 2 валидатора, 1 модель, другой сама сущность формы...
Сам я вот так думаю сделать:
Код действия контроллера.
PHP:
$user = new User;
$user->login = Request::getPost('login');
$user->password = Request::getPost('password');
$user->email = Request::getPost('email');
$user->NameFamily = Request::getPost('NameFamily');
$user->validate('save');
$errors = $user->getErrors();
$captcha = Request::getPost('captcha');
if (empty($errors['captcha'])) {
	$errors['captcha'] = 'Введите слово с картинки';
}
elseif (!Validate::captcha($captcha)) {
	$errors['captcha'] = 'Введите правильно слово с картинки';
}
if (count($errors) > 0) {
	echo 'register is true';
}
else {
	var_dump($errors);
}
Как вы думаете, целесообразно ли так поступать?
И как вы делаете валидацию в подобных случаях?
 

WMix

герр M:)ller
Партнер клуба
ответный вопрос , а что ты понимаешь под формой, это action или всеже model?
по мне форма (вернее request типа post с параметрами) это action, отсюда формой управляет контроллер.
но я форму вырезаю в отдельный класс, и работаю практически как с моделью, setResquest, isValid, getValues
по этой причине она такая же модель
 

vanicon

Новичок
ответный вопрос , а что ты понимаешь под формой, это action или всеже model...
Да форма это отдельная модель, но проблема не в этом.
Смотрел как в других фреймворках создаются, специальные сущности типа форма регистрации, и туда это правило уже можно было запихнуть, но на странице регистрации нужно выводить все сообщения об ошибках, а как я уже вышел писал получается у нас 2 валидатора, 1 модель, другой сама сущность формы...
 

MiksIr

miksir@home:~$
Модель - это набор данных. Все-равно откуда они пришли, из базы или из post. Когда это станет ясно - вопросы отпадут сами собой. В данном случае будет две модели - одна представляющая данные post, другая представляющая данные базы.
 

MiksIr

miksir@home:~$
Валидировать и там и там. Частично валидаторы пересекуться, частично - нет. В принципе можно из модели POST убрать валидаторы, которые будут исполняться в модели базы и выдавать ошибки обеих моделей, но лично я предпочитаю дублировать.
 

WMix

герр M:)ller
Партнер клуба
с одной стороны формуляр думает что имя пользователя это буквенноциферное значение длиной не менее 3 символов
с другой стороны в базе может быть только один пользователь с ником vanicon.

вот и думай как правильно, завязывать форму на базу данных, или в controller отлавливать ошибки обоих уровней
 

Absinthe

жожо
Я считаю что модель должна валидировать данные, но только те которые относятся к ней...
Это без вариантов.
Но в контроллере никто это и не делает. Не упоротые же совсем.
 

WMix

герр M:)ller
Партнер клуба
вот только не говорите что на каждый линк типа ?xyz=abcd вы создаете модель! конечно такие простые данные обрабатываются в контроллере
я часто пишу в контроллере нечто подобное
PHP:
$this->_request->getParam('id',1)
где сообщаю что в случае пустого id используй 1, я могу часто писать
PHP:
if(!$xyModel->find($this->_request->getParam('id',1))){ /* бла бла */}
и это логика контроллера, между линком и формой разница малюсенькая, вопрос только компромиса, когда эти проверки имеет смысл выносить за пределы
 

Ragazzo

TDD interested
WMix
>когда эти проверки имеет смысл выносить за пределы
вопрос вообще решается просто - есть обособленная часть предметной области, которая инкапсулирует бизнесс-логику какого-либо самостоятельного объекта - таки модель. что в ней должно быть? - таки тесты подскажут :D
шучу я)
 

WMix

герр M:)ller
Партнер клуба
я понимаю, момент сложности, вмещается ли в один экран, сложность проверки, свичи, не важно.
представим поле типа селект, после выбора которого, форма отправляется и ... , и это происходит только если... , или большую кнопку купить (которая по понятным причинам должна отправляться почтой), или неважно что, но это явно простая форма, я напишу это в контроллере, а уже после подумаю, есть ли смысл создавать форму как отдельный класс. и тесты писать не буду, там всего 5 кликов (конечно смотря какой проект :))
 

AmdY

Пью пиво
Команда форума
Не нужно заморачиваться насчёт трёх букв, добавьте ещё пару, одна из них будет V, обозначающее валидацию, которую можно использовать и в контроллере, и в модели, и во вьюхе.
 
  • Like
Реакции: WMix

Ragazzo

TDD interested
WMix
ну как бы в том то и дело программиста определить где нужно, а где не нужно что-либо, решаешь то ты)
 

fixxxer

К.О.
Партнер клуба
Вот я долго думал над таким вопросом.

Есть модель пользователя, со всеми понятными полями.
Теперь у нас есть форма регистрации, где есть
1) поле "повторный ввод пароля",
2) капча.

Куда девать эти поля? Дублировать поля и валидации в форме - нехорошо, пихать password2 и (омг) капчу в UserModel - тоже нехорошо.

Я его решил, но вы меня назовете оверинженерастом :D
 

Ragazzo

TDD interested
fixxxer
в нормальных FW, модели для валидации инпута(и прочей фигни) отделены от моделей самой бизнесс-логики ;)
 

fixxxer

К.О.
Партнер клуба
понятно, что отделены, вопрос в отсутствии дублирования кода на общие поля

алсо, я отказываюсь считать форму моделью. =) хотя понимаю такой подход
 

Ragazzo

TDD interested
не вижу в приведенном твоем примере дублирования. у тебя что в AR будет поле repeat_pass или captcha? И дублирование спорный момент, один фиг в form-model будут те же поля что и в ar-model. :S
 

fixxxer

К.О.
Партнер клуба
Ну вот у меня в UserModel есть валидаторы и фильтры на, скажем, email и username, и я совершенно не хочу их копипастить в форму.

С двумя полями выглядит нестрашно - а если их 20?
 

Ragazzo

TDD interested
fixxxer
хз, я давно когда-то для себя решил проводить валидацию лишь в form-model, и таким образом не париться о том что потом можно сменить "хранилище" данных, это также дает хорошее преимущество для API и прочего, вообщем ты понимаешь ;) . Да в AR тоже есть свои rules, но они больше БД-зависимые чтоли, вида length, type и т п.
 

MiksIr

miksir@home:~$
Ну я свое мнение тоже высказал, но в общем нужно смотреть по ситуации. Например, в Yii мы можем захотеть сделать activeform, соответственно почти все правила валидации должны быть в модели формы. В модели базы те ограничения, которые нужны базе.
Вот что делать с такими вещами, как проверка уникальности логина... я до конца не решил - по разному поступаю.
 

fixxxer

К.О.
Партнер клуба
Ну в общем я сделал так:
1) все поля, валидаторы и фильтры не в самой модели, а в Fieldset
2) форма, как и модель, содержит Fieldset
3) fieldset можно клонировать целиком или частично и расширять
4) форма умеет initFromModel
 
  • Like
Реакции: WMix
Сверху