Ako funguje Nette\database vrstva

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

Zdravím,
A prejdem k veci:
Začal som študovať databázovú vrstvu v nette no a v dokumentácii som narazil na nasledujúci zápis:

foreach ($database->table('book')->order('title')->limit(5) as $book)
{
    echo $book->title, ' (', $book->author->name, ')';
    // ekvivalentní s $book['title'], ' (', $book['author']['name'], ')';

    foreach ($book->related('book_tag') as $book_tag) {
        echo $book_tag->tag->name . ', ';
    }
}

Ten prvý riadok by som ešte chápal, ale hneď to prvé echo obsahuje zápis $book->author->name , čo ma absolutne odrovnal. Dúfal som, že ten prvý riadok vráti výsledok selektu, teda nejaký objekt, ktorý databáza vacia. A z neho cez foreach získavame riadky. To dávalo zmysel, kým som nenarazil na to $book->author->name. Vie mi niekto vysvetliť čo znamená to author->name??? Som z toho somár. Ja by som to normálne zapísal jedným dotazom ako left join ale tu sa deje niečo čo je ako z iného vesmíru. Kľudne by som bral, keby bola dokumentácia aj tri krát dlhšia, ale neni…
Tiež by som potreboval vysvetliť význam zápisu $book->related('book_tag')
Ďakujem.

Editoval Čamo (7. 5. 2014 13:39)

David Matějka
Moderator | 6445
+
0
-

dobre je to vysvetleno v anglicke dokumentaci

tl;dr; – cizi klice a sloupecek author_id v tabulce book ukazujici na tabulku author

Pitrrs
Člen | 6
+
0
-

Taky jsem to řešil před pár dny, co to znamená (taky začínám). Je právě super, když (nejjednodušeji v Admineru) si vytvoříš závislosti (viz v tutorialu např. post_id u příspěvku a post_id (u komentářů) což je 1:N vztah) a pak tímto příkazem jednoduše a elegantně vytáhneš právě ty komentáře, které patří k příspěvku.

Aspoň tak jsem to pochopil já :)

Čamo
Člen | 798
+
0
-

Nič nepomáha :(
Dalo by sa napísať miesto
$book->author->name
toto
$book->related(‚author‘)->get(‚name‘) ???

Takto je to v quickstarte. Nechápem, aký je rozdiel medzi tými dvoma zápismi.

Editoval Čamo (7. 5. 2014 16:04)

David Matějka
Moderator | 6445
+
0
-

ne, related('foo') je pro smer 1:N, ref('author) (nebo jen ona zkratka author) je pro opacny smer – N:1

tedy kdyz mas tabulky:

book
----
id
title
author_id ----\
              |
author        |
-----         |
id <----------/
name

tak ta knizka ma prave jednoho autora, pouzijes tedy

$book->ref('author')
//nebo jen
$book->author

( ^^ to ti vrati jeden radek (ActiveRow))

kdyz chces vypsat vsechny knizky autora, pouzijes ono related

$books = $author->related('book');

( ^^ to ti vrati kolekci radku (Selection), kterou muzes projit ve foreach-y)

Editoval matej21 (7. 5. 2014 16:20)

Čamo
Člen | 798
+
0
-

matej21
Ok díky zatiaľ.

Čamo
Člen | 798
+
0
-

Edit
Matej21
Nechcem byť zlý, ale nedáva to zmysel. Autorov môže byť tiež viac a potvrdzuje to aj ten select, čo je v dokumentácii pod tým kódom:
`SELECT * FROM author WHERE (author.id IN (11, 12))
Potom samozrejme tá schéma nedáva zmysel. Lebo tabuľka author by v tom prípade mala obsahovať book_id knihy a nie naopak(tb. Book obsahuje author_id)
Hilfe!

Editoval Čamo (7. 5. 2014 16:56)

Mysteria
Člen | 797
+
0
-

@Čamo: Prostě a jednoduše, $book->autor->name, znamená, že z tabulky book se podle IDčka autor_id přepneš do tabulky autor a z něho vybereš name.

Naopak $autor->related(‚book‘) znamená, že z tabulky autor (vybraného jednoho záznamu), se dohledají všechny záznamy z tabulky book, kde je autor_id stejné, jako IDčko vybraného autora.

Čamo
Člen | 798
+
0
-

Mysteria
Skús mi teda vysvetliť to where id in(11, 12).
Lebo to môže vrátiť dva výsledky.

Editoval Čamo (7. 5. 2014 17:00)

David Matějka
Moderator | 6445
+
0
-

@Čamo: samozrejme, ze knizka muze mit vic autoru. v tomto modelovem prikladu se ale pocita s tim, ze ma jen jednoho. Spravne by ona relace mela byt M:N, ale to uz by to zbytecne komplikovalo. Proste knizka muze mit pouze jednoho autora. To, proc je dotaz

SELECT * FROM author WHERE (author.id IN (11, 12))

je kvuli optimalizaci.

Vybiras treba 5 knizek, ktere maji ruzne autory.

$books = $context->table('book')->limit(5);

ty pak prochazis a chces k nim vypsat autora

foreach($books as $book) {
	echo $book->author->name;
}

Nette database si hned pri prvni iteraci uvedomi, ze $book->author budes chtit i pro dalsi knizky. Takze si je vsechny projde a zjisti, ze ty knizky (tech 5, co si vybral), maji autory 11 a 12, proto polozi ten dotaz uvedeny vyse

Editoval matej21 (7. 5. 2014 17:05)

Čamo
Člen | 798
+
0
-

matej21
Aha, už niečo začínam cítiť.