Undo místo ověřování – handler se zpracovává později, než je záhodno

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
Mikulas Dite
Člen | 756
+
0
-

Ahoj,
mám skoro vyřešené, jak vracet uživatelské akce, ale drhne mi jeden handler.

Jde o to, že na nějakém produktu (Nette route třeba Product:5) mám odkaz na smazání, resp. na

public function handleDelete()
{
	$undo = $this->product->delete();
	$this->flashMessage(Html::el('a')->href($this->link('undo!', array('undo_id' => $undo->id)))->setText("Vrátit zpět"), 'persist');
}

To přináší dvě věci: kliknutí na link mě vrátí na původní stránku. Paráda. Jenomže ta entita už neexistuje (uživatel jí přece zrovna smazal) a protože ověření probíhá už v actionDefault($id), hodím si chybu, že produkt neexistuje. Nechci tu kontrolu přesouvat z action do render, protože jiné handlery už s připravenou entitou pracují.

Handler handleUndo($undo_id) by se zavolal až později.

Quick and dirty jsem dal handleUndo do startupu

public function startup()
{
	parent::startup();
	if ($undo_id = $this->getParam('undo_id')) {
		$this->handleUndo($undo_id);
}

Ale pochopitelně mě to nenechá spát. Jaké řešení navrhujete?

_Martin_
Generous Backer | 679
+
0
-

Co kdyby s tím počítala business logika a smazání by byl nějaký příznak? Entitu by to našlo, ale z meta informací by vědělo, že je smazaná. Případně, namísto řešení signálem to řešit jinou akcí – to by snad nemělo být proti ničemu.

Mikulas Dite
Člen | 756
+
0
-

To jsem právě nechtěl, undo je feature, která nesouvisí s tou entitou. Navíc bych v každé musel mít ještě tu property. Takhle se o to stará vrstva nad tím.

Editoval Mikulas Dite (7. 6. 2011 18:43)

Filip Procházka
Moderator | 4668
+
0
-

Nejčistší řešení je nic nemazat a nastavovat jenom příznak.

Další možnost je mít undo jako akci (popř. s backlinkem, aby se vrátil na původní stránku), pak se nebude provádět kontrola v actionDelete.

Můžu se tě zeptat, jak obnovuješ zpět třeba smazaný článek?

Mikulas Dite
Člen | 756
+
0
-

Chtěl jsem to mít tak, aby samotné tabulky nemuseli o undo vědět.

Mám tabulku undo (user_id, table, data), ze kterých případně revert zápis vrátí. (Resp. se o to stará entitní obálka a delete rovnou vrací undo id.)

Zatím jsem to zlepšil tak, že produkt z id získávám lazy, tzn. nejpozději v renderu při predávání do šablony, ale už ne v akci a handlery se dostanou ke slovu.

Filip Procházka
Moderator | 4668
+
0
-

To mi přijde jako dobré řešení.

Řešíš nějak obnovu referencí? Co kaskáda? Co když někdo zavolá delete v query?

Fakt by mě to zajímalo (stačí teoreticky), jestli to neni tajne :)

Editoval HosipLan (7. 6. 2011 20:15)

Mikulas Dite
Člen | 756
+
0
-

Reference chystám tak, že tabulka undo bude mít ještě něco jako required_by – to se zavolá ještě před původním undo. Tohle je lepší než příznaky, protože se závislosti nemusí vypisovat ručně (no, možná by to šlo nějak získat).

Kaskáda mě taky moc netrápí, protože se záznamy klidně můžou odstraňovat automaticky a aplikace akorát uloží undo s required_by.

Naštěstí to zatím nemám na tabulkách, které se na něco odkazují, ale až to budu psát, bude mi tahle část jasnější. Beru to spíš jako experiment, takže to možná celé překopu : ) To jestli se ukáže, že to jenom trošku někde drhne