Про валидацию 
Вчера сходил на встречу клуба “Вышиби мозг”, послушал доклад на тему “Валидация в Ruby on Rails”. Я и раньше не был сторонником Рельсов, а теперь у меня появился еще один повод их не любить. Все потому, что я не согласен с двумя соглашениями этого фреймворка:
1. Код валидируется в модели;
2. Модель должна быть ActiveRecord, иначе валидацию необходимо реализовывать самостоятельно.
На мой взгляд правильнее использовать такие соглашения:
1. Код валидируется в одном классе (месте);
2. Правила валидации определяются по имени параметра и едины для всего проекта;
3. В модель передаются только валидные данные;
На практике данные требования реализуются довольно просто - создается класс ValidDataObject в котором прописываются правила валидаци (не буду приводить содержимое класса, так как его реализация очевидна). Тогда метод контролера выглядит следующим образом:
$u = new Model_User( new ValidDataObject($_POST) );
}
Примечание. Для обработки ошибок валидации нужно использовать исключения. Тогда в коде выше добавится еще try/catch.
Преимущества такого подхода:
1. Облегчается повторное использование правил валидации, да и самих моделей;
2. Все ограничения (параметры валидации) собраны в одном месте и нигде не дублируются (отсюда - их легко править);
3. Задавать ограничения можно когда угодно, не опасаясь пропустить какую-то модель.(лично я никогда не делаю валидацию сразу после создания модели, жду когда модель будет окончательно готова).
Аргумент о том, что только модель знает особенности реализации бизнес-логики не канает, так как валидация - не часть бизнес-логики, а часть технической реализации, т.е. на нее влияют ограничения используемых технологий и ничего более.
подписаться на блог
Sam Dark
Гость
По-моему всё немного не так:
1. Повторное использование модели в вашем случае усложняется, добавляется бессмысленный копипейст кода контроллера, если надо работать с моделью в нескольких местах. Тем более, один набор правил вы вряд-ли примените к двум разным моделям.
2. В модели они также собраны и не дублируются.
3. Дело привычки.
Кстати, не уверен, что требуется именно AR. В Yii, который в какой-то степени ориентировался на рельсы, валидация вынесена в CModel, от которого уже наследуется CActiveRecord.
Andy
Гость
2. Модель должна быть ActiveRecord, иначе валидацию необходимо реализовывать самостоятельно.
А вот нихрена подобного. В Rails3 можно подмешать валидацию вообще в любой объект! И этот объект не обязательно должен сохраняться в БД. Например, валидацию можно подмешать в класс Message, который отвечает за отправку сообщений на почту.
Andy
Гость
Вот, кстати, мои мысли про валидацию: http://torqueo.net/why-zend-form-validation-is-bad-or-how-to-do-proper-validation/
Там еще много людей в комментах высказалось.
Evgeny Sergeev
Веб-разработчик, автор блога codeart.ru
Sam Dark,
1. по-моему код контролера будет копипаститься в любом случае. Так как инициализировать модель нужно в любом случае.
2. В модели собраны толкько часть правил относящихся к данным модели. Чтобы увидеть общую картину придется просматривать все модели.
3. Никогда нельзя быть уверенным в том что одни и те же данные одинаково валидируется в разных моделях.
4. Валидация в модели так же нарушает принцип персональной ответственности
Sam Dark
Гость
Evgeny Sergeev,
1. То инициализировать, а то ещё и вызов валидации копипейстить.
2. Т.е. вы хотите запихать в один класс-валидатор правила для вообще всех моделей? Если нет, то видение общей картины как раз ухудшится. Да и вообще, работа обычно идёт с одной моделью (при добавлении и редактировании), так что на правила в остальных можно не смотреть.
3. Ну так я и предлагаю в разных моделях писать разные правила.
4. Что это за принцип такой?
Evgeny Sergeev
Веб-разработчик, автор блога codeart.ru
Sam Dark,
1. а какая разница передать в модель “$params” или “new DataValidation($params)?
2. Да, я хочу запихать в класс-валидатор правила валидации всех данных проекта. А объект (модель) обязать в качестве данных принимать только объекты реализующие интерфейс DataValidator.
3. Т.е. в одной модели длина пароля должна быть от 8-10 символов, в другой от 6-8 и это нормально на Ваш взгляд? (пример притянут за уши, но реальный пример тоже можно придумать)
4. Принцип персональной ответственности (Single Responsibility Principle) – класс обладает только 1 ответственностью, поэтому существует только 1 причина, приводящая к его изменению.
Валдиация данных - 1-ая задача;
Сохранение, загрузка данных - 2-ая задача.
Leave a Reply