Обработка форм, валидация ввода

A1x

Новичок
можно еще представить модель как просто данные и методы бизнес-логики
Модель может получать/сохранять данные из разных равноправных источников данных
Источниками данных могут быть ORM, XML, CSV, HTML форма и т.д.
Каждый источник данных имеет свои правила валидации и отображения данных на поля модели.
Модель ничего не знает о возможных источниках данных и содержит только данные и бизнес логику
 

Духовность™

Продвинутый новичок
Каждый источник данных имеет свои правила валидации и отображения данных на поля модели.
такого быть не может! Если ты получаешь данные их какого-то источника, то ты их должен сначала преобразовать в "нормальный" вид (напрмиер, перекодировку сделать), а уже потом взять эти данные и попробовать сунуть их в модель. Вот на этом этапе валидация и нужна, что бы к объекту ВАЗ нельзя было приделать свойство "колесо" типа "колесо от МАЗа".
 

A1x

Новичок
triumvirat что значит "нормальный" вид и какую перекодировку?
примерно так:
PHP:
DataLayer::useLayer('Form');
$form = DataLayer::getResource('User');
$user = $form->load(); // тут же валидация формы
if ($form->hasErrors()) {
    while ($err = $form->getError()) {
        // ...
    }
    .......
} else {
    DataLayer::useLayer('ORM');
    $orm = DataLayer::getResource('User');
    $orm->save($user); // здесь тоже может быть валидация
    if ($orm->hasErrors()) {
           // если есть ошибки валидации при сохранении в БД то сохранения не происходит
            while ($err = $orm->getError()) {
                // ...
            }
    } else {
        // ура
    }

}
 

crocodile2u

http://vbolshov.org.ru
A1x
Ну а чем противоречит твой пример моим, например, словам? Ясный пень, что, если форма должна быть проверена дополнительно (ну то же подтверждение пароля, скажем) - то мы должны каким-то образом эту проверку осуществить - причем до того, как данные формы попадут в БД.
 

A1x

Новичок
crocodile2u да вобщем то ничем не противоречит, просто на практике я не делаю валидацию модели перед сохранением в базу - вся валидация делается при приеме формы.

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

PHP:
DataLayer::useLayer('Form');
$form = DataLayer::getResource('User')->useValidationClass('Validation_User_Form_Register');
 

MiksIr

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

A1x

Новичок
MiksIr
я в предидущем посте дописал - это можно сделать в виде иерархии классов валидаторов которые потом впрыскиваются
 

MiksIr

miksir@home:~$
Т.е. если у вас есть 10 моделей, с которыми происходит работа из форм, и формы которых отличаются для пользовательской части и админской (как пример) вы создадите еще 20 отдельных классов с правилами валидации? Ну ладно.

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

A1x

Новичок
я ничего не имею против чтобы делать всю валидацию перед записью в базу...

взять например подтверждение пароля - не имеет отношение к валидации в модели

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

я думаю лучше иметь 20 классов с четкой структурой чем лепить костыли

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

Духовность™

Продвинутый новичок
Вопрос: если мы в объект User пихаем логин больше заданного кол-ва символов, что должен сделать этот объект? Возвратить false? Кинуть исключение? Возвратить текст ошибки?
 

gerasim

Новичок
A1x
взять например подтверждение пароля - не имеет отношение к валидации в модели
Есть еще такой подход: в той же модели прописываются поля, которые должны проверяться, но которых в самой модели (таблице) нет. Они помечаются как "not in DB", соответственно, валидация по ним идет, а запись в базу этих полей не происходит. Как раз для таких случаев с полями пароль и подтверждения пароля, или когда пароль надо сменить ( поля "новый пароль" и "текущий пароль").
 

A1x

Новичок
gerasim
я знаю, но мне это не очень нравится. и не нравится все время таскать в модели правила валидации, которые используются относительно редко, хотя это экономия на спичках

triumvirat!!! Заканчивай уже пить на форуме ;)
 

whirlwind

TDD infected, paranoid
А при чем здесь вообще модель, валидация и запись в базу данных? Есть объект в составе домена, у объекта есть атрибуты - валидация выполняется при изменении атрибутов. Где тут вообще база? Может оно через rpc сохраняется или вообще на бумажке распечатывается. Независимо от того насколько и где persistent объекты модели, классы модели реализуют все ограничения, то есть требования к модели. Если они этого не делают, а делает какой либо сервисный слой торчащий ногами из модели сбоку, то это просто путанная архитектура. Пользователю модели не нужно знать столько тонкостей, что бы работать с классами модели.

-~{}~ 18.08.10 01:27:

ЗЫ. Не, вообще подобный A1x подход он говорит за качество кода. Если кто помнит топик про уровни развития разработчика, это избыточная декомпозиция, что далеко не в начале и даже не в середине. Но золотая середина походу только с тестами приходит. Когда тебе на одно простое действие снаружи модели надо зафикстурить стопицот классов, сразу вспоминаешь бритву оккама.
 

Духовность™

Продвинутый новичок
Заканчивай уже пить на форуме
Я серьезно!

Есть модель пользователя, примитивный объект User. Мы объявляем тип и ограничения каждого свойства этого объекта. Что делать, когда объекту модели присваивается невалидное значение?
 

seine

Новичок
Интересная тема получилось, позновательная, и очень хочется услышать ответ на вопрос triumvirat:
(на всякий случай повторю)

если мы в объект User пихаем логин больше заданного кол-ва символов, что должен сделать этот объект? Возвратить false? Кинуть исключение? Возвратить текст ошибки?
 

MiksIr

miksir@home:~$
"Возвратить false" или "Кинуть исключение" и "Возвратить текст ошибки (когда его попросят)"
 

A1x

Новичок
выставить какой-то признак что обнаружены ошибки (или выбросить исключение), собрать информацию об ошибках и выдать ее по требованию

так
PHP:
if ($user->validate()) {
    $user->save();
} else {
    $errors = $user->getValidationErrors();
    ....
}
или так
PHP:
try {
    $user->save();
} catch (ValidationException $e) {
    $errors = $user->getValidationErrors();
    ....
}
информацию об ошибках потом можно потом вывести при повторном показе формы для исправления.... или по почте разослать
 

weregod

unserializer
whirlwind +1
работаем над API системы, очевидно, валидация входных данных модели должна делаться моделью, иначе через стандартное API можно порушить данные системы ;)
а что делать при невалидных данных - вопрос реализации, и вообще не вопрос
 
Сверху