Sa zicem ca am urmatorele 3 entitati: User, Movie, Comment.
Intre User si Movie e o relatie ManyToMany. iar intre User si Comment e o relatie OneToMany.
Am nevoie ca sa obtin, toti utilizatorii unui film, cu comentariile lor.
Daca fac asa:
{% for movie in movies %}
{% for user in movie.users %}
{{ user.comments }}
{% endfor %}
{% endfor }
Problema e ca {{ user.comments }} imi afiseaza mai multe date decat ar trebui, deoarece, in spate, se face un query de genul: SELECT * FROM comments WHERE user_id = x
Dar trebuie de luat in calcul faptul ca user-ul x are comentarii si de la alte filme, dar mie imi trebuie doar pentru filmul respectiv, adica sa tina cont de chainning-ul asta: movie -> users -> comments.
In Laravel, cu Eloquent, trebuia asta functiona bine, by default. Aici in Doctrine vad ca e altfel.
Cum as putea rezolva problema?
Multumesc.
Nu m-am jucat prea mult cu Symfony, deci s-ar putea sa spun prostii.
Cum ai definite entitatile (Entity) si relatiile? Poti sa dai copy paste la cod? De asemenea cum iei movies in controller?
eu nu inteleg de ce trebuie sa fie o relatie intre movie si user. normal ar fi user has many comments, comment belongs to user/movie, movie has many comments.
Si eu sunt de parere ca structura este gresita. Structura la care ma gandesc ar fi:
User has many Comments
Movie has many Comments
Comment created by User
Movie > Comments > User (legat de comments printr-o proprietate createdBy).
Si in felul asta ca sa obtii ce vrei iei Movie cu toate comentariile si la fiecare comentariu ai putea afisa de cine este creat si astfel iese si un singur foreach.
De ce am nevoie de o relatie ManyToMany intre Movie si User? Sa presupunem ca User ar fi un actor al filmului, ca sa fie mai clar. Un Movie poate avea mai multi actori, iar un actor poate face parte din mai multe filme. Daca tot nu e clar nici asa, atunci renunt la analogie, si va dau exemplul meu concret. Am 3 entitati: Report, Query, Issue. Asocierile care le-am facut, sunt in felul urmator: Movie = Report, Query = User, Comment = Issue.
Deci intre Report si Query trebuie sa fie o relatie ManyToMany deoarece, un Report poate contine mai multe Query-uri, iar un Query poate fi folosit in mai multe Report-uri. Intre Query si Issue, e relatie OneToMany, pentru ca un Query poate avea mai multe issues.
Pe mine ma intereseaza sa extrag Report -> queries -> issues, deci un raport impreuna cu query-urile lui, iar pentru fiecare dintre aceste query-uri, sa fie si issue-urile care au fost gasite in urma acelui Query, dar sa fie issue-urile doar de la raportul respectiv.
Prima remarca ar fi folosirea termenului “user”. E un cuvant prea generic, eu mereu insist pe folosirea unui cuvant specific. Deci daca in cazul tau user este un actor, de ce sa nu folosesti Actor?
De ce nu iti faci o metoda de business in care sa obtii exact datele pe care le vrei, fara sa te lasi “pe seama” magiei doctrine șcl? Concret, eu as avea un serviciu care sa imi dea date despre raport,
// declarat ca serviciu in containerul de Symf,
// sa zicem la cheia 'reports.repository'
class ReportsRepository
{
public function extended()
{
// aici apelezi ce vrei tu din doctrine sa-ti dea datele, ideal faci tu SQLul optimizat de care ai nevoie
return $collection;
}
}