výceúrovňový výběr z databáze v presenteru

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

Celkem rozumím tomu, jak nasypat do prezenteru data z databáze a vykreslit je. Jak to ale udělat, když potřebuji 2 úrovně? Například mám databázi s tabulkou knih (knihy), druhou autorů (autori) a třetí mi linkuje autory ke kniham (autoriknih). Teď chci vypsat nějaké knihy (podle výběru) a k nim i autory. V prezenteru bych pak potřeboval něco jako

{foreach $knihy as $kniha}
  <h1>{$kniha->nazev}</h1>
  <ul>
  {foreach $autori as $autor}
  // TADY ALE POTREBUJI KOD DONUTIT ABY TO BYLI
  // $autori->where('autoriknih.knhy_id = ?',$kniha->id)
    <li>{$autor->jmeno}</li>
  {/foreach}
  </ul>
{/foreach}
Bertram
Člen | 75
+
0
-

Nejlepší asi bude,když si SQL dotaz sestavíš tak,aby ti vracel všechny tyto údaje najednou.
Potom ti bude stačit v šabloně pouze jeden foreach.

pcs
Člen | 22
+
0
-

Jak ale odliším v jednom cyklu stejné resp. různé položky když budu mít např. tato data

kniha.id | kniha.nazev | autor.jmeno
1        | Kniha 1     | Petr
2        | Kniha 2     | Jirka
2        | Kniha 2     | Pavel
3        | Kniha 3     | Tonda
Bertram
Člen | 75
+
0
-

Možná ti přesně nerozumím,ale co takto:

	$sql = "SELECT kniha.id, kniha.nazev, autor.jmeno
		FROM kniha, autor, autoriknih
		WHERE kniha.id = autoriknih.kniha_id
		AND autor.id = autoriknih.autor_id";

a pak

	{foreach $knihy as $kniha}
		{$kniha->id} | {$kniha->nazev} | {$kniha->jmeno}
	{/foreach}

Editoval Bertram (11. 3. 2011 13:43)

pcs
Člen | 22
+
0
-

Já jsem to asi špatně popsal. Já z těch dat, které získám tvým pojetím nebo v mém pojetí takto:

$sql = "SELECT kniha.id, kniha.nazev, autor.jmeno FROM autoriknih
        LEFT JOIN kniha ON kniha.id = autoriknih.kniha_id
        LEFT JOIN autor ON autor.id = autoriknih.autor_id"

a získám tato data

kniha.id | kniha.nazev | autor.jmeno
1        | Kniha 1     | Petr
2        | Kniha 2     | Jirka
2        | Kniha 2     | Pavel
3        | Kniha 3     | Tonda

Vypsat ale potřebuji toto.

Kniha 1
- Petr
Kniha 2
- Jirka
- Pavel
Kniha 3
- Tonda

Bez nette jsem to řešil tak, že jsem měl jeden cyklus, který vybíral knihy a v něm vnořený druhý, který k nim dohledával autory.

Bertram
Člen | 75
+
0
-

Toto mě napadá jako rychlé řešení,ale nevím jestli ti jde jen o prostý výpis,nebo se na to budou vázat další operace.To už by ale asi chtělo jinný přístup od počátku.

{foreach $knihy as $kniha}
  <h1>{$kniha->nazev}</h1>
  <ul>
    {foreach $knihy as $knihaAutori}
      {if $kniha->nazev === $knihaAutori->nazev}
        <li>{$knihaAutori->jmeno}</li>
      {/if}
    {/foreach}
  </ul>
{/foreach}

Nebo v sql dotazu použít agregační funkci GROUP_CONCAT, aby jsi dostal autory jako řetězec oddělený nějakým separátorem.

Editoval Bertram (15. 3. 2011 20:04)

pcs
Člen | 22
+
0
-

Opět jsem narazil na tento problém a zjistil jsem, že mnou požadované řešení je již popsáno v dokumentaci. Pokud někdo na tuto stránku zabrousí tak vězte, že správné řešení je:

{foreach $knihy as $kniha}
  <h1>{$kniha->nazev}</h1>
  <ul>
    {foreach $kniha->related('autor') as $autor}
      <li>{$autor->jmeno}</li>
    {/foreach}
  </ul>
{/foreach}

Jak prosté, že? :-)

Editoval pcs (28. 1. 2012 16:41)

hrach
Člen | 1838
+
0
-

@pcs: posledni priklad naznacuje vzrah 1:N, predpokladam ale z uvodniho prispevku, ze se jedna o vztah M:N, reseni je tedy:

{foreach $books as $book}
	<h1>{$book->title}</h1>
	<ul>
	{foreach $book->related('kniha_autor') as $knihaAutor}
		<li>{$knihaAutor->author->name}</li>
	{/foreach}
	<ul>
{/foreach}