Vazebne tabulky a jejich podba v modelu ENTITY+REPOSITORY+MAPPER

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

mam dve entity odpovidajici svym tabulkam v databazi.
Napriklad Kniha a Ctenar, ty maji sve repozitare a mappery …

Tyto entity maji byt provazany vstahem M:N, jak se takova vec vlastne v entity repository mapper modelu implementuje, zaklada se dalsi entita jen pro vazebnou tabulku a pojmenovava se treba VazbaCtenarKniha ? To se mi zda ponekud kostrbate i kdyz by to jiste fungovalo.

Nebo se entite kniha i ctenar preda repozitar vazebne tabulky, takze vlastne neni potreba entita vazebne tabulky, entita kniha misto toho bude mit metodu pridatCtenare($idCtenare) a entita Ctenar bude mit metodu pridatKnihu() … pak je ovsem otazkou zda maji tyto metody ihned vytvorit vazbu nebo si provazana id jen ulozit do vnitrniho stavu a nechat je ulozit az metodou uloz vlastniho prislusneho repozitare, v takovem pripade metodam entity nemusim predavat repozitare vazebne tabulky, ale budu je muset pouzivat z repozitare Knihy a Clanku … Cele se mi to nezda, nekapnul jsem za celou dobu na reseni ktere by se mi zdalo elegantni. Muzete mi prosim nekdo s bohatsi zkusenosti poradit jak nejlepe na to ? Predem diky za drahoceny cas :-)

artemevsin
Člen | 61
+
0
-

ahoj,
asi nebudu zrovna ten někdo s bohatší zkušenosti, ale podobný problém jsem vždy řešil tak, že jsem měl entitu Ctenar, která obsahovala kolekci Knih (tj. druhá varianta co popisuješ). Entita Ctenar má metodu pridatKnihu(Kniha $kniha), které předávám objekt Kniha. V repozitáři pak mám metodu uloz(Ctenar $ctenar), která se postará o to, že se uloží (resp. aktualizuje) jak samotný čtenář, tak i jeho knihy. Tj. veškerou logiku persistování objektu Ctenar včetně všech jeho vazeb přenáším do repozitáře čtenáře.
Stejně tak to mám i ze strany Knihy, která se postará o to, že při jejím uložení se uloží i všechny její vazby.
Takže s vazební tabulkou pracuji jak v repozitáři Ctenare tak i v repozitáři Knihy, přece je součásti obou entit, resp. jejich vazeb.
Zatím mi toto řešení vyhovovalo. Do DB ukládám až konečný stav entity (co když knihu nejdřív přidám a po chvíli ji zase smažu) a její vazeb, tak ušetřím pár dotazů do DB. Ale rád bych se nechal přiučit právě od někoho zkušenějšího.
PS. jinak jsem tady někde zahlédl, že hlavní téma říjnové posoboty bude Model, tak si myslím, že asi pro nás oba to bude velkým přínosem :)

Azathoth
Člen | 495
+
+1
-

Ahoj,
nejpohodlnější je používat Doctrine, která se o tohle stará sama. Prostě si definuješ vazbu, určíš si vlastnící stranu a Doctrine se ti stará o odebírání a přidávání.

Pokud máš jen M:N vztah bez dalších atributů, tak bys to měl mít bez entity. Každý čtenář bude mít pole knih, které přečetl a každá kniha pole lidí, kteří ji přečetli. Repozitář (přístupný z jiných částí aplikace) by se o to propojování neměl starat, protože bude knihy a čtenáře přidávat/ubírat tím, že budeš sahat na ta pole a řešit by to měl až mapper, který podle změny v tom poli udělá příslušné změny ve vazebné tabulce.

Co se týče repozitáře vazebné tabulky, tak záleží na tom, jak pracuješ se změnami v entitách. Například Doctrine neukládá změny hned, ale až po zavolání entityManager->flush, kdy entityManager (služba) zkontroluje všechny změny v entitách a podle toho provede update a insert/delete řádků ve vazebných tabulkách.
Ale jestli přímo tvé entity volají metody na persistování do databáze, tak ti asi nezbývá nic jiného, než poslat těm entitám repozitář vazebné tabulky…ale pak by s tím repozitářem měly pracovat jen ty entity, abys neměl možnost upravovat vazebnou tabulku přes ten repozitář odjinud.

Vazebná entita je zapotřebí až ve chvíli, kdy bys k tomu M:N vztahu chtěl něco přidat, například od kdy do kdy to četl nebo jak se mu to líbilo. To bych pak pojmenoval například entita Reading, která by měla čtenáře, knihu, začátek a konec čtení, hodnocení.

Editoval Azathoth (20. 9. 2015 23:24)

zac24
Člen | 41
+
0
-

Díky … no, vypadá to, že právě na doctrine opravdu vyzrál čas a nejspíš ocením jeho přínos :-) Protože tohle je spousta mravenčení kolem elementárních věcí, kterými by se člověk raději moc nezdržoval.