Menu v databázi – podkategorie
- motorcb
- Člen | 552
Zdravím.
Snažím se dynamicky vykreslovat menu z databáze. V menu bych chtěl mít
i podkategorie (teoreticky neomezený počet):
Sport
Letni
Fotbal
Cyklo
...
Zimni
Hokej
....
Nářadí
Elektrické
Vrtačky
Příklepové
...
Manuální
...
Proto jsem navrhl takovouto struktutu db:
CREATE TABLE menu (
`id` INTEGER NULL AUTO_INCREMENT DEFAULT NULL,
`name` VARCHAR(50) NULL DEFAULT NULL,
`up_category_id` INTEGER NULL DEFAULT NULL,
PRIMARY KEY (`id`)
);
Kde up_category_id odkazuje na nadřazenou kategorii.
Nyní ale nevím jak sestrojit SQL dotaz, kterým bych vypsal všechny
kategorie, jejich podkategorie, jejich podkategorie…
Bude na to nějaká rekurze, nebo postupuji špatným směrem?
Díky za nakopnutí :)
- vvoody
- Člen | 910
Ja by som to skusil tak, ako radi dokumentacia, vkladanim bloku sameho do seba. Skusim napisat nieco z hlavy, co by sedelo na tvoj pripad:
{block #menu}
<ul>
{foreach $menu as $item}
<li>
<a n:href="...">{$item->name}</a>
{? $selection = $menu->related('menu','up_category_id')}
{if $selection->count()>0}
{include #menu, menu => $selection}
{/if}
</li>
{/foreach}
</ul>
{/block}
Takto by si vlastne do sablony vlozil len selection korenovych poloziek menu:
$this->template->menu = $database->table('menu')->where('up_category_id',NULL);
Vo vysledku by si mala Nette Database pri prvom requeste nacachovat tie prvky menu a pri kazdom dalsom pokladat len jeden jednoduchy dotaz. Alebo lepsie asi bude cachovat cele menu.
- motorcb
- Člen | 552
vvoody:
Dobřééééé ty :)
Jen si dovolím trošku doopravit :-) Funguje perfektně :)
{block #menu}
<ul>
{foreach $menu as $item}
<li>
<a n:href="...">{$item->name}</a>
{? $selection = $item->related('forum_category','up_category_id')}
{if $selection->count()>0}
{include #menu, menu => $selection}
{/if}
</li>
{/foreach}
</ul>
{/block}
Máš u mne pivo :)
- Majkl578
- Moderator | 1364
iNviNho napsal(a):
Neporušuje sa týmto MVC pattern?
Imho samotné rekurzivní vykreslování s MVC nijak nesouvisí/neodporuje.
Ak mám v databázi 200 kategorií a pre každu robiť query, nie je to spomalujúce?
Jistě, ale to je otázka optimalizace (zde zjevně nevolat related v šabloně pakliže vím, že nette\database neumí takovou věc optimalizovat/kešovat).
- iNviNho
- Člen | 352
Pretože pre človeka, ktorého to robím, tak má v DB cca 180 kategorií a na localhoste mi píše, že sa v tomto momente ⇒ http://ekotrim.sk/…kategoria/15 robí 280 queries a trvá okolo 2500 ms, čo je podla mna vela …
preto premýšlam nad iným algoritmom na vykreslovanie, resp. nahradit to query nejakou funkciou, ktorá bude pracovat s fetchnutou tabulkou kategorie a vnom vyhladavat a nie sa znova a znova dotazovat do DB …
posledný komentár vyzerá sexy = http://stackoverflow.com/…-through-php
Editoval iNviNho (14. 11. 2013 10:20)
- iNviNho
- Člen | 352
Jasné, ja som si ten select stále naplnal novým a novým querym, prerobil som to
<?php
? $select = $presenter->zistiPotomkovKategorie($item["id_kat"])}
?>
Presenter
<?php
public function zistiPotomkovKategorie($id) {
$pole = array();
foreach ($this->sql as $dotaz) {
if ($dotaz->id_rodic == $id) {
$dotaz = $dotaz->toArray();
array_push($pole, $dotaz);
}
}
return $pole;
}
?>
a ešte pred tým v actionMetode
<?php
$sql = SelectModel::vyberVsetkyKategoriePreSelect();
$this->sql = $sql;
?>
v praxi funguje nádherne :)