Form, Database Explorer, prosím o radu
- MW
- Člen | 626
Zdravím, prosím o názor k tomuto kódu.
Je toto správný postup?
V presenteru je načtený formulář z továrny. Mám jeden Model, který vrací explorer->table(), tj settings->getSettingsTable().
Ptám se především proto, že se mi nejak nezdá, jestli je dobře ten
setDefaults()->fetch()->, jinak jsem to tam nedostal a
trochu nechápu, proč, když to vrací následující prvek… podle doc..
A také, jestli je opravdu practice, to takto obsluhovat v presenteru, ted
myslím ten update().
Takto jsem to pochopil z dokumentace.
Předem moc děkuji za názor a rady, vracím se k Nette po 6ti letech, tak se učím hodně věcí znovu :).
protected function createComponentNastaveniForm(): Form {
$form = $this->nastaveniFactory->create();
$form->setDefaults($this->settings->getSettingsTable()->fetch());
$form->onSuccess[] = function ($form) {
$this->settings->getSettingsTable()->update($form->values);
$this->flashMessage("Nastavení uloženo.");
$this->redirect('Nastaveni:');
};
return $form;
}
Editoval MW (27. 6. 2024 21:19)
- Šaman
- Člen | 2668
MW napsal(a):
Ptám se především proto, že se mi nejak nezdá, jestli je dobře ten setDefaults()->fetch()->, jinak jsem to tam nedostal a trochu nechápu, proč, když to vrací následující prvek… podle doc..
Vždyť nevoláš $form->setDefaults()->fetch()
, to by
opravdu nedávalo smysl.
Ty voláš $form->setDefaults( $db->query()->fetch() )
.
Fetch je v tomto případě potřeba, protože do setDefaults
máš předat pole dat, nikoliv aktivní databázový dotaz. (Resp. ty nad db
nevoláš query, ale to je jedno, obecně přistupuješ k datům a pak si
fetchneš výsledek.)
Navázat obsluhu update v presenteru je ok. Záleží jakou máš strukturu aplikace. Já mám formuláře v modelu, ale používám orm, takže formulář je vedle entity, kterou upravuje. Základní obsluha je pak také navázaná v tom modelu, ale minimálně redirect si má řešit až ten presenter.
Editoval Šaman (27. 6. 2024 21:36)
- MW
- Člen | 626
Šaman napsal(a):
MW napsal(a):
Ptám se především proto, že se mi nejak nezdá, jestli je dobře ten setDefaults()->fetch()->, jinak jsem to tam nedostal a trochu nechápu, proč, když to vrací následující prvek… podle doc..
Vždyť nevoláš
$form->setDefaults()->fetch()
, to by opravdu nedávalo smysl.
Ty voláš$form->setDefaults( $db->query()->fetch() )
. Fetch je v tomto případě potřeba, protože dosetDefaults
máš předat pole dat, nikoliv aktivní databázový dotaz. (Resp. ty nad db nevoláš query, ale to je jedno, obecně přistupuješ k datům a pak si fetchneš výsledek.)Navázat obsluhu update v presenteru je ok. Záleží jakou máš strukturu aplikace. Já mám formuláře v modelu, ale používám orm, takže formulář je vedle entity, kterou upravuje. Základní obsluha je pak také navázaná v tom modelu, ale minimálně redirect si má řešit až ten presenter.
Moc díky! Jen ten fetch() není asi úplně šťastně popsán v DOC… nebo jsem to přehlédl.
Editoval MW (27. 6. 2024 21:45)
- Šaman
- Člen | 2668
Aha, sorry, teprve teď jsem pochopil jak jsi to myslel. Nj, je to divný.
Nějak jsem myslel, že voláš fetchAll
, nebo
fetchPairs
– to druhé je právě pro plnění třeba
selectboxů ve formuláři.
Nevím co přesně ten formulář zpracovává, z toho dotazu to chápu tak,
že ho nakrmíš jedním (prvním?) řádkem z tabulky
settingsTable
. Doporučuji si dumpnout data dřív, než je
předáš do toho formuláře. Protože tady se řeší dvě různé věci –
formulář a načtení dat z databáze.
- m.brecher
- Generous Backer | 905
@Šaman
Já mám formuláře v modelu, .....
To mě přijde jako zajímavý koncept.
V jaké formě máš tyto formuláře vytvořené ?? Jako traity, které obsahují metodu createComponent<Form>(), nebo jako plnohodnotnou třídu poděděnou z UI\Control, která „obaluje“ vlastní Form ??
Poznámka: @KamilValenta používá opačný koncept než ty, kdy umisťuje modelové třídy do složky presenteru a má tak pohromadě vše co presenter používá – formuláře, modelové třídy, šablony a samotný presenter.
- Šaman
- Člen | 2668
@mbrecher : Jako FooFormFactory. Typicky mám třídu Entity, její FormFactory a většinou GridFactory. Někdy i Datasource, pokud je to entita rozlezlá přes několik tabulek, někdy i třída pro práci s kolekcí entit. Všechno to mám pod modelem, protože když sáhnu na entitu, budu asi upravovat i vsechny ostatní. A stále to souvisí s datovou vrstvou, nikoliv s prezenční vrstvou.
Že to má Kamil jinak vím, proto píšu že nastavování v presenteru může být zcela legit.
- m.brecher
- Generous Backer | 905
@MW
$this->settings->getSettingsTable()->fetch()
Metoda fetch() knihovny Explorer se dá použít pro čtení řádků z objektu Selection v cyklu např.:
$articles = $database->table('article');
while($article = $articles->fetch()){
echo $article->title;
}
nebo mimo cyklus dává smysl pokud vybíráme podle sloupce, který má unikátní index a je tak zaručeno, že výběr z tabulky Selection obsahuje pouze jeden řádek:
$article = $database->table('article')->where('title', $title)->fetch(); // sloupec title má UNIQUE index
Pro práci s jedním řádkem databázové tabulky ve formuláři nejčastěji používá výběr pomocí metody get($id), nebo where(…) uvedený výše.
Když si rozebereme Tvoje dotazy do databáze:
$this->settings->getSettingsTable()->fetch()
$this->settings->getSettingsTable()->update($form->values)
Tak mě tam chybí výběr řádku z tabulky nějakým parametrem, který by se měl ve formuláři aktualizovat, – třeba $id. Otázkou je, co se skrývá za getSettingsTable(), jestli tam není ten parametr schovaný.
- Kamil Valenta
- Člen | 844
m.brecher napsal(a):
Poznámka: @KamilValenta používá opačný koncept než ty, kdy umisťuje modelové třídy do složky presenteru a má tak pohromadě vše co presenter používá – formuláře, modelové třídy, šablony a samotný presenter.
Jen bych upřesnil, že ne do složky presenteru, ale do složky modulu.
Modelové třídy jsou vždy v adresáři model. Takže když otevřeš
adresář modulu, máš v něm všechny jeho modely, presentery, šablony,
neony.
Jen „assets“ jsou ve www, takže zatím je modul na dvou místech (v app a
ve www). Asi by i to šlo mít na jednom místě a rozhodil by to až
deploy…
- Kamil Valenta
- Člen | 844
MW napsal(a):
protected function createComponentNastaveniForm(): Form { $form = $this->nastaveniFactory->create(); $form->setDefaults($this->settings->getSettingsTable()->fetch()); $form->onSuccess[] = function ($form) { $this->settings->getSettingsTable()->update($form->values); $this->flashMessage("Nastavení uloženo."); $this->redirect('Nastaveni:'); }; return $form; }
Mně by tady vadilo, že se v presenteru volá update() přímo nad
selectionou. Metoda presenteru tedy sahá přímo do db bez vědomí modelu,
což není dobře (projeví se, až přibude požadavek na přístupová práva,
logování změn apod.)
Za mě by bylo lépe, kdyby přímo modelová třída settings měla svou metodu
update().
Tedy:
$form->onSuccess[] = function ($form) {
$this->settings->update($form->values);
$this->flashMessage("Nastavení uloženo.");
V počátku ta metoda klidně jen vše přenese do $this->getSettingsTable()->update(), ale když se později něco změní, upravíš jen update() v settings.