Ako funguje Nette\database vrstva
- Čamo
- Člen | 798
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
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
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á :)
- David Matějka
- Moderator | 6445
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
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
@Č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.
- David Matějka
- Moderator | 6445
@Č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)