dzheka3d
@dzheka3d

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

Всем привет! Я совсем запутался в этом ООП.
Мне нужно создать список объектов например user. Каждый объект будет содержать в себе поля (их много. Имя фамилия, адрес, фото, логин, количество постов, подписчиков и т.д.).
Получить такой список объектов из базы просто... Делаем запрос:
SELECT * FROM `users`
Мы получим список объектов users. Вроде профит, НО...

Если в другом запросе нам нужно вывести пользователей "лайкнувших" пост. Опять выполняем запрос:
SELECT u.* 
FROM `likes` lk 
INNER JOIN `users` u ON u.`id` = lk.`user_id`
WHERE lk.`post_id` = 1775

Мы опять получили список тех же объектов, но фактически после второго запроса мы будем создавать объекты уже заново в куске кода, который не подойдет для первого запроса. Получается, что и в том и другом случае мы можем создать разные объекты, если будем указывать разные поля в запросе. Красиво получилось бы так:
И в первом и во втором запросе получаем только поле ID пользователя, а потом передаем эти ID в метод getUsers, который выводит объекты users по единому правилу. А тот в свою очередь делает запрос в БД, в котором во WHERE IN() указывает полученные ID нужных пользователей. Но в этом случае получается два запроса, причем второй будет содержать кучу ID-шников в IN(). Что явно плохо...

Вот вопрос, как сделать так, чтобы можно было использовать единый метод для получения объектов user?
Или все-таки это правильно, создавать новый объект в каждом запросе, ведь в приложении встречаются не только запросы по лайкнувшим пост пользователям, но и подписчики, поиск по по пользователям, список недавно зарегистрированных пользователей и так далее... Выходит для каждого такого запроса нужно создавать свои объекты users.

Прошу прощение за такое изложение вопроса, надеюсь я нормально объяснил... может устал за целый день...
  • Вопрос задан
  • 440 просмотров
Решения вопроса 1
Decadal
@Decadal
Давайте начнем с того, что база данных это не про ООП. База данных это то, что выросло из примитивных файликов на жёстком диске, куда выплёвывается всякая разная информация, родившаяся во время работы с программой.
БД ставит себе цель работать очень быстро с гигантскими объемами данных. БД имеет свою фишечку по красоте собственного устройства, называется нормализацией.
Если вы будете пришивать ко всему, что увидите, ООП, очень скоро заметите что время разработки просто упрется в бесконечность.

А теперь касательно вашего примера: у вас есть класс который называется юзер. В него попадают данные после запроса всех юзеров - и он с ними работает. А потом в него попадают данные после запроса юзеров, поставивших лайки - он работает и с ними.
Все. Это потолок, шедевр, ООП тут сделало свою работу. Можете кодить спокойно дальше.
Пока не узнали что модель юзера может меняться в зависимости от ситуации, и где-то вам понадобится модель юзера с моделью аватарки внутри, а где-то - с моделью аватарки и ещё и моделью токена...
Пока что все хорошо.
Ответ написан
Пригласить эксперта
Ответы на вопрос 2
@miksir
IT
То, что вы говорите - называется патерном Identity Map и реализовано в некоторых ORM системах, например, в Doctrine.

> Вот вопрос, как сделать так, чтобы можно было использовать единый метод для получения объектов user?

Получая данные из базы проверять - есть ли в кеше сущность с таким же идентификатором.

> Или все-таки это правильно, создавать новый объект в каждом запросе

Правильно, имхо, что бы был только один объект с одним идентификатором, а если нужно иное поведение - сказать это отдельно.
Ответ написан
Комментировать
DirecTwiX
@DirecTwiX
"display: flex;" уже предлагали?
Добавлю свои пять копеек к ответу Decadal

Советую прочитать доку по ларавелю, или хотя бы lumen (микрофрейморк, брат ларавеля) в частности раздел про Eloquent. Многое должно встать на место.
Т.е. у нас есть модель пользователя:
$user = User::find(1); //пользователь с id = 1
$users = User:all(); //все пользователи


Далее мы можем настроить отношения моделей и, например, сказать, что у пользователя могут быть созданные им посты. Тогда если у нас есть пользователь $user, мы сможем получить все посты, которые он лайкнул, просто написав
$likedPosts = $user->posts
К слову, это тоже самое, что и
$likedPosts = Posts::where('author_id', $user->id)->get()


В итоге всё получается очень красиво. Все поля пользователя, грубо говоря, есть в классе User, а все поля постов пользователя есть в User->posts, которые (посты) являются экземплярами класса Post.

https://laravel.com/docs/5.5/eloquent
https://laravel.com/docs/5.5/eloquent-relationships
Ответ написан
Ваш ответ на вопрос

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

Похожие вопросы