Pri neexistujucom zázname má Model vrátiť false alebo vyhodiť výnimku?
- srigi
- Nette Blogger | 558
Ako Model používam Doctrine. Nejaká entita modelu má asi cca takúto formu (api):
<?php
class Pages extendes BasePages // BasePages extends Doctrine_Record
{
public static function getByUrl($url, $lang)
{
$q = Doctrine_Query::create()
->from('Pages p')
->leftJoin('p.PagesI18n i')
->leftJoin('i.Languages l')
->where('i.url = ?', $url)
->andWhere('l.code = ?', $lang);
return $q->fetchOne();
}
}
?>
Rozmýšľam ako sa správať keď sa záznam nenájde. Horeuvedený kód
vtedy vráti cca prázdny objekt Doctrine_Record
, ktorý si musím
„ocheckovať“ v presenteri. Tak ma napadlo, že či checkovačku nehodiť
už do tej model metódy a vracať false.
V presenteri ale na základe toho overenia aj tak vyhadzujem pri prázdnom výsledku výnimku, tak rozmýšľam že nebudem vracať ani false a výnimky budem vyhadzovať v Modely.
Ktorý prístup je z hľadiska MVP najsprávnejší, poradte best practise.
THX.
- jiriknesl
- Člen | 56
Co se čistoty týká, vyjde to podle mě nastejno. Používám oba přístupy a vracení null nebo false je praktičtější než NotFoundException.
if(null === ($article = $articlesPersistence->fetchByUrl($url, $lang))
$this->throw404;
// ... prace s clankem
vs:
try
{
$article = $articlesPersistence->fetchByUrl($url, $lang);
// ... prace s clankem
}
catch (PersistenceNotFoundException $e)
{
$this->throw404;
}
- _Martin_
- Generous Backer | 679
Jednodušší kód může být výhodou. Ono zpracování výjimky taky může být o něco málo roztahanější, než uvádíš:
try {
$article = $articlesPersistence->fetchByUrl($url, $lang);
} catch (PersistenceNotFoundException $e) {
$this->throw404();
}
// ... prace s clankem
Ale je to spíš otázka, co komu vyhovuje. U výjimek nacházím tu
výhodu, že je má potom model (z pohledu zpracování chyb) konzistentní
chování – je jedno, zda volám fetchByUrl
nebo předávám ID
v konstruktoru ($model = new Article($id)
) – zpracování chyb
je vždy stejné.
P.S. Když píšeš PHP kód, použij prosím zápis /--php
, aby
se použil zvýrazňovač syntaxe.
Editoval _Martin_ (12. 2. 2010 12:20)
- Ondřej Mirtes
- Člen | 1536
Osobně vracím výsledek dotazu:
Metoda modelu:
return $this->db->fetch(....);
A v Presenteru kontroluji na začátku render metody existenci záznamu takto:
if ($result == NULL) {
throw new BadRequestException('Record not found.');
}
Přijde mi to úsporné a dostačující :)
- Patrik Votoček
- Člen | 2221
Přesně jak říka srigi. Pokud je výsledkem 0 záznamů tak vrátit NULL. Pokud je v dotazu na model chyba tak jasně exception. Ještě teda já to řeším tak že chci aby mě v případě kdy očekávám pole a výsledek je 0 záznamů vrátím místo NULL prázdný array() kvuli foreachy…
- Blizzy
- Člen | 149
Pro model není nic výjiměčného, když podle určitých parametrů nenalezne žádná odpovídající data.
Pro presenter už to v určitých případech může být výjimečné, protože se aplikace snaží zpracovávat data, která neexistují, proto by se výjimky tohoto typu měly vyhazovat v presenteru.
Tímto způsobem by se mělo postupovat u všech případů, kde se rozhoduje, zda použít výjimku (teď není řeč o řídících výjimkách).
- _Martin_
- Generous Backer | 679
Blizzy napsal(a):
Pro model není nic výjiměčného, když podle určitých parametrů nenalezne žádná odpovídající data.
OK, asi bych to měl upřesnit: je rozdíl, pokud jde o vyhledávání a nebo o získání konkrétního modelu. V prvním případě je výsledek nejistý a lze čekat, že se mi může vrátit prázdné pole (nebo nějaký prázdný objekt, přes který lze iterovat,…). Ve druhém případě si žádám konkrétní model (článek s ID 5/článek se jménem/… záleží na identifikátoru). Pak očekávám výjimku, pokud model neexistuje. Je to samé, jako se soubory na disku.