@Alk90
php, mysql, jquery, css, html, api

Как правильно получить составные данные из базы и сложить их в одну сущность?

Всем привет!
Появилась у меня в голове такая путаница. Есть несколько страниц, на которых выводятся посты. У постов соответственно, есть автор, заголовок и текст + сопутствующие данные вроде даты, кол-ва просмотров и т.д.
Получается что для того чтобы правильно выводить пост на всем сайте, нам нужна одна точка получения данных. Скажем класс PostsModel это и есть тот класс. Он работает с базой данных и делает все, что связано с постами. И тут как раз проблема.
Нам нужно передать в класс PostsView, который отвечает за вывод поста в виде HTML, не только данные поста, но и данные об авторе. А значит объект User так же должен получаться в одной точке, например UsersModel.
Ведь мы не можем просто взять и в PostsModel выполнить JOIN необходимых полей из таблицы Users? Это ведь нарушает правила единой ответственности? т.е. пост не должен знать ничего о полях пользователя.
Значит есть вариант получить данные постов, создать из них объекты, положить в коллекцию постов, а в коллекции создать метод, который сможет добавить объект User к нужному посту коллекции. Надеюсь я верно рассуждаю.
После запрашиваем в модели UsersModel всех пользователей, которые были авторами выбранных постов и кладем к каждому посту если есть совпадения.
Но в таком случае, получается, что вид поста будет общаться с методами пользователя.
Пожалуйста, направьте на путь истинный, совсем запутался.
Что почитать по этой теме, может какие-то паттерны или где подсмотреть...
  • Вопрос задан
  • 195 просмотров
Пригласить эксперта
Ответы на вопрос 4
@EvgeniiR
https://github.com/EvgeniiR
Немножко не ответ
Для класса PostsModel:
Автор Поста является потомком Поста.
Пост для автора - Родитель.
Пост для даты поста - Родитель.

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

Совет - развивайте критическое мышление и фильтруйте информацию, не верьте всему в интернете, даже если у этого 100500 плюсов на каком-нибудь ресурсе типа Хабра/SO/Medium/Тостер и т.п.


Алексей Коновалов,
нам нужна одна точка получения данных.

Нам не нужна "единая точка получения данных". У вас есть ваши модели(сущности, доменные модели) - это компонент вашей системы отвечающий за часть бизнес-логики.
Так же у вас есть представления данных. Представлений данных может быть множество. Не нужно реиспользовать одну и ту же модельку для логики/записи и для чтения(представления, UI).
Выбрали данные из БД(raw SQL/Eloquent/DQL смапленный на DTO, что угодно)
->заполнили ими структуру которая сформирована исходя из нужд клиентского модуля(Frontend`а вашего),
-> привели к нужному формату(json etc.) и отдали на фронтенд

Он работает с базой данных и делает все, что связано с постами. И тут как раз проблема.

Очень хорошо что вы подметили что это проблема, серьёзно. Именно по этому "Active Record" - антипаттерн.
Некоторые, к большому сожалению, годами к этому не могут придти, того больше - отстаивают каждое архитектурное решение какого-нибудь Laravel не с позиции инженера, а с позиции религиозного фанатика.

Модели для записи ничего про HTTP, Request и представления знать не должны. Модели на чтение по сути просто структуры данных.
Ответ написан
xmoonlight
@xmoonlight Куратор тега PHP
https://sitecoder.blogspot.com
Для класса PostsModel:
Автор Поста является потомком Поста.
Пост для автора - Родитель.
Пост для даты поста - Родитель.
и т.д.
Ответ написан
anton_reut
@anton_reut
Начинающий веб-разработчик
Внутри объекта Пост можно создать новый объект Юзер, передать в него id юзера (id юзера ведь у тебя указан для каждого поста, то есть кто автор) и потом уже выводить имя юзера и всё остальное. Короче "композиция": ассоциация, при которой используемый объект создается внутри класса.
В результате у тебя будет одна коллекция постов и всё будет в ней, а не две "кучки" - Посты и Юзеры.
Ответ написан
php666
@php666
PHP-макака
PostsView, который отвечает за вывод поста в виде HTML
никакого PostsView быть не должно - достаточного одного View - это, по сути, шаблонизатор, с буферизацией вывода. Что, по твоему, должен делать PostsView?

Что почитать по этой теме
"Архитектуру корпоративных приложений" Фаулера. Главу "источники данных".

Ведь мы не можем просто взять и в PostsModel выполнить JOIN необходимых полей из таблицы Users?
Я в своем самописном фреймворке так и сделал. Есть метод для JOIN в моей ORM, он возвращает многомерный массив объектов, где каждый конечный элемент (на твоем примере) будет объект модели Поста и Пользователя. Почему так? Потому, что сделать так:

<html>
  Текст поста: <?=$post->getText()?><br>
  Автор поста:  <?=$post->getAuthor()->getName()?> <!-- это самое сложное -->
</html>


- сделать своими силами - очень, очень нетривиальная задача.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы