Vazebne tabulky a jejich podba v modelu ENTITY+REPOSITORY+MAPPER
- zac24
- Člen | 41
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
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
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)