Наследование сущностей Doctrine: введение

Приветствую вас в серии видео, которая будет посвящена такой теме, как наследование сущностей Doctrine. Что это такое, зачем это нужно и для чего это может пригодиться — об этом поговорим в этом видео. Это вводная часть, небольшое введение о том, для чего это нужно и зачем это вам может понадобиться.

Записываю эту серию видео исходя из своей ситуации, с которой столкнулся, разрабатывая свой Symfony-проект. Из-за того, что я не знал понятия наследования сущностей, как им правильно пользоваться и как это можно использовать на практике, я потерял огромное количество времени, которое можно было бы использовать более разумно и эффективно.

Давайте рассмотрим общую ситуацию, с которой мне пришлось столкнуться и которая сподвигла на создание такой серии видеоуроков. Мой проект, который я разрабатывал на фреймворке Symfony, содержал в себе такие сущности, как Page (страница) и Post (запись).

Структура проекта была чем-то похожа на структуру сущностей, которые идут по умолчанию в таком популярном движке сайтов, как WordPress. Там страницы — это некие статичные страницы, а посты — это сущность, которая имеет дату создания, которая обновляется, имеет рубрику и теги. Также есть статичные страницы, которые имеют категорию, какие-то quiz-опросы и так далее.

Общая структура сущностей

По сути, и у страниц, и у постов есть некая общая часть. Страницы могут содержать title (заголовок), content (контент), comments (комментарии), и то же самое могут содержать посты. У них есть общая часть и есть отдельная часть, которая принадлежит каждой из этих сущностей. Налицо у нас получается типичная ситуация наследования — некий родитель Content (я называл это «контент») и дочерние элементы, такие как Page и Post.

Изначально у меня проект был сделан немного по-другому. Я создал проект таким образом, что у меня были отдельная сущность Page и отдельная сущность Post. У страниц были поля title, content, comments, и у записей тоже были поля title, content, comments. Каждая сущность была отдельной.

Какая же из-за этого потом возникла проблема? Почему я решил поменять полностью всю структуру своего Symfony-проекта и сделать её именно в наследуемом виде, чтобы у меня был родительский элемент, содержащий общие поля?

Проблемы при раздельных сущностях

Одна из самых главных ситуаций, из-за которой я решил всё переделать — мне нужно было выбрать информацию и из сущности Page, и из сущности Post. Когда эти сущности были отдельными, мне нужно было осуществить поиск по полям title, content и comments и по страницам, и по записям.

Тут я столкнулся с такой проблемой, что используя библиотеку Doctrine сделать выборку по двум независимым сущностям достаточно сложно. Приходится писать какие-то сложные запросы, что-то выдумывать — очень сложная ситуация получается.

Эта ситуация сподвигла меня на поиски, и я пришёл к выводу, что важно организовать структуру проекта таким образом, чтобы был родительский элемент и дочерние элементы. Тогда поиск осуществляется достаточно просто — мы ищем по полям title и content, которые имеет родительский элемент. Выборки из этих сущностей становятся очень простыми.

Ещё одна большая проблема при раздельных сущностях была с комментариями. Комментарии были и у страниц, и у постов. Мне приходилось создавать отдельные сущности комментариев и отдельные ссылки на то, какой сущности они относятся. Когда я перешёл на систему наследования, стало намного проще — комментарии привязываются к родительскому элементу Content. Независимо от того, где он находится — в странице или в посте — комментарий является единой прикреплённой сущностью.

Кроме того, вам будет значительно проще расширять проект, если сущности с общими характеристиками организованы подобным образом. Допустим, появляется ещё какой-то элемент помимо страниц и постов — например, товары магазина или ещё что-то. По сути, это тоже контент сайта, но имеющий свои отличия. Таким образом вы можете достаточно просто расширять контент, который будет находиться на вашем сайте.

Такая вводная информация — просто хотел обозначить общую проблему, которую я буду решать в следующей серии видео. Мы с вами посмотрим, каким образом можно решить эту ситуацию.