Къде да валидираме в MVC модела?

Странно, но последните няколко дни постоянно се сблъсквам с един въпрос „Къде да валидираме“, и постоянно трябва да обяснявам, че валидацията на данните ВИНАГИ, ама наистина ВИНАГИ, става в модела, а не в контролера. За съжаление,  масово  по мрежата примерите се дават с валидация в контролера, и ако хванете нещо като CodeIgniter, най-вероятно ще се подхлъзнете. Причините за тази грешка са две. Едната е, че Сульо и Пульо, къде знаят и не знаят, почнали да дават акъл, лошо няма в това, но  подвежда хората. Втората, по-основната причина е, че така е по-лесно, и в малки проекти изглежда логично, и че не пречи.

Защо обаче трябва да е в модела? За да разберете, отговорите си на въпроса „Какво е модел“. Това е мястото където се държат данните и тяхната логика (най-грубо казано). Кой трябва да се грижи за валидността на данните? Този, който ги държи, и се грижи за тях, или някой друг? представете си, че вие работите, взимате заплата, но някой друг ви харчи парите, без да го е грижа какви са вашите планове. Кофти е, нали? Точно това се случва, когато валидирате в контролера.

Вижте, в малки проекти наистина няма значение, на местата където даден модел се вика 1-2 пъти само и общо взето се получава, че за всеки метод в контролера имате 1-2 метода в модела, и те не се ползват другаде. Обаче при по-големи проекти, особено такива направени с акъла си, един модел се ползва на много места. Тогава какво трябва да направите? Да имате няколко еднакви валидации на тези няколко места? Това е тъпо, определено. А какво ще стане, като започнете да променяте правилата за валидация? Трябва да ги смените на всички места, което отново е тъпо.

Моделът е самостоятелна единица, грижеща се за данните, а може би най-важното нещо, които трябва да направим с данните е да ги валидираме.

Започнахте ли да схващате? Дано, ще си спестите много проблеми в бъдеще.

Искам да направя едно уточнение, в контролера може да има валидация на данните, но само ако в следствие на тази валидация, контролера трябва да изпълни различно действие. Данни, които ще се мениджърът от модела, се валидират САМО от модела. Ааа да, и още едно уточнение, в едно предишно мое видео за MVC бях казал, че валидацията се прави в контролера. Еми, както казах „Сульо и Пульо….“. Определено тогава греших в разбиранията си, и се бях подвел по едни фреймуркове……

Ако си зададете въпроса „Ако сега взема тоя модел, и го сложа в друг проект, ще работи ли както трябва, ще се счупи ли, ще ми се дънят ли данните, без да се налага да пипам други части от системата“ (в контекста на данни) и си отговорите „Да“, значи всичко е наред с модела, и сте го написали правилно. Модела взима данните чрез параметри, параметрите контролират неговото поведение, той не трябва да се интересува кой го вика, къде връща.

Сега идва въпроса, как да връщаме грешките от модела, и има няколко начина. Единият, особено подходящ за езици като Java и C#, е класическия try/catch. Паролата е прекалено къса? просто модела ще си хвърли изключение, и извикващият го обект ще има грижата да се оправя. В тези езици това наистина е удачен начин, понеже изключенията са обекти, и въобще цялата им платформа е изградена върху тези концепции. Обаче в света на PHP, въпреки, че можем да ползваме същата техника, да си създаваме свой Exception класове, и да ги връщаме, не винаги това е най-удачният вариант. Въпрос на вкус, както се казва. Един прост елегантен вариант е следният:

class UserModel{
public function registerUser($username,$pass){
$return[‘success’]=false;
$return[‘errors’]=null;
if(mb_strlen(trim($username)){
$return[‘eroors’][]=“username_too_short“;
}
//други валидации, дали имеето е заето…..
if($return[‘errors’]==null){
//нямам грешка, пише SQL за запис в базата или там каквото трябва да правим
$return[‘success’]=true;

}
return $return;
}
}

И така, нещото което го извиква, винаги получава отговор, и ако success===true, значи е минало, ако е false, значи нещо се е объркало и търси в масива errors какво се е объркало.

Разбира се, това е елементарен пример, само за да покаже концепцията, може да го направите по-мазен, ако искате, но основната идея е, винаги да има отговор, който по подразбиране е false, и само и единствено като сме сигурни, че всичко е минало както трябва връщаме true.

Ами какво става с FormValidation класовете, дето толкова се бутат по тия frameworks? Просто е, ползвате ги, когато има смисъл да ги ползвате, но масото тези библиотеки НЕ стават за валидация в модела, понеже те взимат директно данните от $_REQUEST (и подобни), а модела взима от параметри. Имате няколко опции, едната е да хванете някой FormValidation, и да го модифицирате за работа с параметри на модела. Вариант 2, да си направите базов клас за модела, който реализира методите за валидация и да може да си опишете правилата. Вариант 3, статичен клас с методите за валидация, и на всеки метод на модела, ръчно си описвате всеки параметър.

Всеки един от тези варианти е добър, така че помислете, обмислете, разберете, и ако сте съгласни с мен, почнете да пишете валидациите където трябва. Ако ли не, майаната ми 🙂

105 thoughts on “Къде да валидираме в MVC модела?

  1. Оги

    Ванка БЛАГОДАРЯ ТИ ЗА СВЕТКАВИЧНИЯ и супер компетентен отговор!
    Ще го обмисля много добре, но мисля да използвам последната ти препоръка.

  2. ДимитърСт

    „Оги Says:
    имам проект на сайт (продуктов сайт, например чащи, чорапи, блузи и блабла) с една база данни и 50 таблици в нея.“

    Били споделил част от тези таблици ..стана ми интересно като спомена 50 (чак толкова много)… ти да не си направил за всеки тип продукт отделна таблица?!

  3. Ванката

    Последно къде се валидират, щото тука в едно видео в края на видеото казвате че е в контролера. Ако е стара тая информация оставете един коментар под видеото за да не се бъркаме начинаещите
    http://gatakka.eu/?p=357 тук казвате че е в контролера

  4. Ванката

    Тук в началото също е обяснено че в контролера става валидация и нормализация на входящите данни http://gatakka.eu/?p=359, явно е добре да се отбележи в самата статия че не е в контролера а в модела , ако е така. Поенже и на мен м истана доста объркано досега в 2те видеа се казва че е в контролера сега в тази статия съвсем друго пише.

  5. gatakka Автор

    @ Ванката в МОДЕЛА. Онова видео е старо, аз за това в това видео казвам, че преди време съм се подвел и аз.

Вашият коментар