Obrácení validačního pravidla formuláře
- Tomáš Jacík
- Člen | 147
Nyní mám v repository validační funkci, která v db ověřuje, zda už název existuje:
public function billingNameExists($name, $reverse = FALSE)
{
if ($name instanceof Nette\Forms\IControl)
{
$name = $name->value;
}
return $this->getTable()->where('b_name', $name)->count() > 0;
}
Ve formuláři jsem ji chtěl použít takto:
->addRule(array($this->customerRepository, 'billingNameExists'), 'xxx');
Jenže ta funkce musí vracet FALSE, aby validace fungovala jak má. Když upravím funkci, aby vracela FALSE, nebude pak univerzální. Zatím jsem to chtěl vyřešit parametrem $reverse. A teď:
- Jde do addRule ta funkce zadat tak, aby se udělala její negace?
- Je vůbec toto zadávání do addRule ok, nebo se to už dělá nějak lépe?
- Je ok z hlediska návrhu mít tu validační funkci v repository?
- Je to v Nette 2.2 pořád repository, nebo se to má nazývat nějak jinak? Všiml jsem si že je tam nyní nový název UserManager.
Díky
- jiri.pudil
- Nette Blogger | 1034
Mně připadá nejlepší nechávat podobné validace na databázi, tzn. neřešit validaci na formuláři, mít nad daným sloupečkem unique a při ukládání odchytávat výjimku s duplicate key. Cokoliv jiného není odolné vůči race condition a zároveň nebudeš muset duplikovat validační pravidlo, až bude potřeba naimplementovat třeba veřejné API.
Ale k tvým otázkám:
Jenže ta funkce musí vracet FALSE, aby validace fungovala jak má. Když upravím funkci, aby vracela FALSE, nebude pak univerzální.
Nerozumím. Co jiného by ta funkce měla vracet? Už z jejího názvu bych očekával, že vrací boolean.
Jde do addRule ta funkce zadat tak, aby se udělala její negace?
Je vůbec toto zadávání do addRule ok, nebo se to už dělá nějak lépe?
Je to naprosto ok. Když si ale tu funkci uděláš statickou a do addRule ji
předáš názvem
(->addRule('CustomerRepository::billingNameExists')
), má to
hned několik výhod: jednak pak půjde standardně znegovat
(->addRule(~'CustomerRepository::billingNameExists')
) a jednak
se ti předá její název i do data-nette-rules atributu, takže si můžeš
dopsat validaci i na straně JS. Na druhou stranu ve statické funkci se blbě
řeší předání závislostí a už jen proto bych se tomu vyhnul, pokud
potřebuješ pracovat s databází.
Je ok z hlediska návrhu mít tu validační funkci v repository?
Může být. Ostatně ta validace je součástí spíše doménové než prezenční logiky.
Je to v Nette 2.2 pořád repository, nebo se to má nazývat nějak jinak? Všiml jsem si že je tam nyní nový název UserManager.
Každý pes jiná ves. Někdo má managery, někdo service, někdo repository, někdo DAO, … Za některými z nich jsou i nějaké návrhové vzory, můžeš si je prostudovat a vybrat si, který název se ti líbí nejvíc.
- Tomáš Jacík
- Člen | 147
Mně připadá nejlepší nechávat podobné validace na databázi …
To máš sice pravdu, ale v tomto případě bych to chtěl validovat ještě před ukládáním, když formulář není zcela vyplněn. Ušetří to uživateli spoustu práce se zadáváním údajů.
Nerozumím. Co jiného by ta funkce měla vracet? Už z jejího názvu bych očekával, že vrací boolean.
Funkce vrací boolean, ale opačný, než potřebuje ta validace pro form. Ve formu potřebuješ FALSE, aby validace prošla (neexistuje), jinde v k´du chceš, aby se funkce chovala podle názvu (TRUE = existuje).
Když si ale tu funkci uděláš statickou …
Statickou ji dělat nemůžu. Neumím si představit, jak bych do ní pak narval repository, aniž bych porušil milion principů :) Takto to tedy v php znegovat nejde?
- Majkl578
- Moderator | 1364
Ad negace:
- pro vestavěné validace se používá tilda:
~Form::FILLED
- Pro negaci vlastního callback validátoru můžeš použít lambda funkci, kde výsledek zneguješ.
Ostatně vlastní lambda validátor bys měl použít tak jako tak, validační metoda někde v modelu by rozhodně neměla očekávat jako parametr instanci IControl.