Používání static u metod vlastních validačních pravidel
- Budry
- Člen | 88
Zdravím,
je to asi zbytečná otázka ale už chvíli se tu patlám s vlastním
validačním pravidlem a stále se mi nedaří nalézt nějaké řešení.
V dokumentaci k Nette 2.0 (pro php 5.3) jsem nic nenašel a pro Nette 0.9 mi
zas řešení nefungovalo.
Vyřešil jsem to tedy následovně:
Do složky models/ jsem přidal složku form_validation/ a do ní umístil soubor MY_Form_validation
models/
|_ form_validation/
|_ My_Form_validation.php
A pravidlo volám přes callback
$form->addText('jmeno', 'Jméno')
->addRule(Form::FILLED, 'Vyplňte vaše jméno')
->addRule(callback('MY_Form_validation::inDatabase()'), 'Toto uživatelské jméno je již registrováno')
Funguje to, jak má (zatím). Ale nejsem si jist jestli je to správné
řešení.
Dá se to takto používat?
Předem díky
Editoval Budry (19. 8. 2011 23:14)
- Filip Procházka
- Moderator | 4668
to je strašně hrozné :))
$model = $this->context->usersModel
$form->addText('jmeno', 'Jméno')
->addRule(Form::FILLED, 'Vyplňte vaše jméno')
->addRule(function ($name) use ($model) {
return $model->findByName($name->value) === NULL;
}, 'Toto uživatelské jméno je již registrováno')
Příklad přepodkládá v kontextu zaregistrovanou službu
usersModel
, která představuje službu, pro práci s uživateli a
má metodu findByName
, která když nic nenajde, tak vrací
NULL
.
- Jan Tvrdík
- Nette guru | 2595
Na použití vlastních callbacků nevidím nic špatného. V tvém
konkrétním případě se ale nelíbí zvolený název třídy –
MY_Form_validation
. Mnohem závaznější problém ale je, že
zrovna unikátnost uživatelského jména nemá moc smysl ověřovat tímto
způsobem, protože si nemůžeš být jist, že v době mezi zavoláním
ověřovacího callbacku a provedením registrace si toto uživatelské jméno
nezaregistruje někdo jiný. (runtime chybám je nemožné předcházet).
- Filip Procházka
- Moderator | 4668
Vadil mi ten statický přístup k databázi. Navíc je ta metoda hodně špatně pojmenovaná.
- uestla
- Backer | 799
Hlavně ten přístup je nesprávný, neboť není atomický. Mezi kroky, kdy se validuje a samotným uložením uživatele se může zaregistrovat někdo jiný se stejným jménem. Tenhle problém by se IMHO měl řešit „surovým“ vložením do databáze a odchycením případné výjimky (porovnat kód výjimky, odlišit kód vracený při vkládání duplicitní položky, apod.).
Někdo by namítl, že se to může odchytávat i s takto navěšeným callbackem, nicméně takto zase může v době, kdy se validuje a zjistí se, že záznam existuje, a samotným uložením, dojít k odstranění daného uživatele z databáze…
Čili „validaci“ na unikátnost zajistit v databázi
(UNIQUE
), existenci pak de facto nekontrolovat.
EDIT:
Přesně jak píše Honza (trošku víc jsem to rozebral)
Editoval uestla (20. 8. 2011 17:05)