Чат Telegram
Группа ВКонтакте
Работа с доктриной. Связь один ко многим: форма комментариев на сайте. Часть 1

Работа с доктриной. Связь один ко многим: форма комментариев на сайте. Часть 1

На прошлых уроках мы написали первую сущность, поработали с формой, стандартной авторизацией и авторизацией через соц сети. Однако в реальных приложениях все намного сложнее: есть многочисленные связи между сущностями, которые надо правильно обрабатывать. К счастью, Symfony в качестве инструмента с базой данных использует Doctrine, которая очень удобна как раз для решения вопросов отношений. Сегодня мы с вами познакомимся с первым типом отношений - ManyToOne/OnyToMany.

Основы ассоциаций в Doctrine

Мы уже делали сущность Post на одном из первых уроков, поэтому мы не будем ничего переписывать, а прямо в ней сделаем отношение с другой сущностью, Comment. Для начала давайте создадим ее.

Код доступен только после покупки курса по фреймворку Symfony 4.

Давайте сначала поразмышляем, как правильно определить отношение между сущностями. У нас есть комментарии и есть публикация. У публикации может быть много комментариев, но комментарий может принадлежать только одной сущности. Отсюда и возникает, что мы должны определить к таблице Post и User отношение ManyToOne, потому как только одному посту и одному пользователю могут принадлежать много комментариев, но не наоборот.

Аннотация ManyToOne принимает несколько аргументов, один из них - targetEntity - является ссылкой (можно указывать как Entity::class, так и полный неймспейс до сущности) на класс для связи, другой inversedBy, где указывается поле для связи. В нашем случае к сущностям User и Post мы позже добавим поле comments. Важно заметить, что связь с двух сторон можно не указывать, потому как доктрина умная и додумает сама, как соединить (а именно по id), но если вам понадобится получить комментарии для всех постов, то удобно достать их через публикацию, хоть это и не очень быстро.

Кстати, @JoinColumn() можно не указывать, доктрина все равно создаст нам такие же поля, как и с ней, однако если вы хотите изменить название поля или референс, то надо использовать данную аннотацию.

Теперь давайте укажем связи в сущностях Post и User, делается это следующим образом:

Код доступен только после покупки курса по фреймворку Symfony 4.

При этом в конструкторе классов Post и User надо определить поле comments как коллекцию объектов:

Код доступен только после покупки курса по фреймворку Symfony 4.

Вы могли заметить небольшие отличия в аннотациях ManyToOne и OneToMany, а именно на то, что у них разные атрибуты - inversedBy и mappedBy. inversedBy указывается в аннотации ManyToOne и указывает на родителя связи, mappedBy же указывают на обратную сторону двунаправленной связи.

При этом не надо указывать @ORM\Column() для полей связи, так как тип связующего поля возьмется по id, и если вы укажете, то аннотация @ManyToOne или @OneToMany просто не выполнится. Теперь можете запускать миграции:

Код доступен только после покупки курса по фреймворку Symfony 4.

Если вы посмотрите в базу, то увидите таблицу comment со следующими полями:

Код доступен только после покупки курса по фреймворку Symfony 4.

Все сработало ровно так, как нам и нужно было.

Добавление комментария

Для добавления комментария к посту мы будем работать с коллекциями. Для этого нам сначала нужно добавить следующие методы в сущность Post:

Код доступен только после покупки курса по фреймворку Symfony 4.

У ArrayCollection достаточно простой API, советую познакомиться с ним по ссылке.
В первом методе мы сеттим Post и проверяем, содержится ли уже в коллекции комментарий с таким id, если нет, добавляем, если да, ничего не делаем. Ну и удаление работает так же просто: вызываем метод коллекции removeElement, куда передаем сущность Comment. Теперь давайте создадим форму:

Код доступен только после покупки курса по фреймворку Symfony 4.

Кажется, все готово, чтобы можно было под постом добавить комментарий. Для этого сначала напишем экшен контроллера PostsController, а потом отрендерим шаблон:

Код доступен только после покупки курса по фреймворку Symfony 4.

Как вы могли заметить, мы по одному роуту и показываем публикацию, и создаем комментарий. Примерно так может выглядеть итоговый шаблон:

Код доступен только после покупки курса по фреймворку Symfony 4.

И вот теперь нам понадобилась связь в сущности Post, так как через post.comments мы достали все комментарии, принадлежащие конкретному посту. Так же вы можете достать все комментария юзера через user.comments в шаблоне или $this->getUser()->getComments() в коде.

Итого

На этом пока все. Еще больше концепций и правил по работе с отношениями мы рассмотрим в следующих уроках.

P.S.

Если у вас будут проблемы с последней версией Symfony или с пониманием работы отношений, пишите вопросы в комментариях.

Комментарии (0)
loader
loader
Логические задачи с собеседований