Hello great people of SO!
First of all, I'm sorry if my english is not very good, but I'm gonna try my best here to describe my problem
I have 3 Models
User.php
___________________________________________________________
| id | name | email | password | created_at | updated_at |
| ... | ... | ... | ... | ... | ... |
| ... | ... | ... | ... | ... | ... |
| ... | ... | ... | ... | ... | ... |
User model relationship:
public function posts() {
return $this->hasMany(Post::class, 'user_id', 'id');
}
Post.php
__________________________________________________
| id | user_id | body | created_at | updated_at |
| ... | ... | ... | ... | ... |
| ... | ... | ... | ... | ... |
Post model relationship:
public function user() {
return $this->belongsTo(User::class, 'user_id', 'id');
}
public function likes() {
return $this->morphMany('likeable');
}
Like.php
_________________________________________________________________________
| id | likeable_type | likeable_id | user_id | created_at | updated_at |
| ... | ... | ... | ... | ... | ... |
| ... | ... | ... | ... | ... | ... |
| ... | ... | ... | ... | ... | ... |
Like model relationship:
public function likeable() {
return $this->morphTo('likeable');
}
Everything works fine, for simple C.R.U.D
The problem comes when I use Laravel Debugbar, I saw so many repetitive queries just to fetch few records:
Ex:
// Let say that I have 5 users
$users = User::all();
foreach ($users as $user) {
$user->load('posts');
}
return $users;
// Result
select * from `posts`.`user_id` 1 ...
select * from `posts`.`user_id` 2 ...
select * from `posts`.`user_id` 3 ...
So I decide to change the method
Ex:
$users = User::all();
$posts = Post::whereIn('user_id', $users->pluck('id')->toArray())->get();
// Result:
select * `posts`.`user_id` in (1, 2, 3, 4, 5)
I no longer see repetitive query, which is good, After solving this repetitive query, I fetch 'likes' from specific posts
Ex:
$users = User::all();
$posts = Post::whereIn('user_id', $users->pluck('id')->toArray())->get();
$posts_likes = Like::where('likeable_type', 'App\Post') // morphMany
->whereIn('likeable_id', $posts->pluck('id')->toArray())->get();
Now here's the problems, I do not know how to pair posts_likes to to it's post
Ex:
$posts = [
{
'id': 1,
'user_id': 2,
'body': 'Lorem ipsum...',
...
},
{
'id': 2,
'user_id': 2,
'body': 'Sit amet...',
...
},
{
'id': 3,
'user_id': 3,
'body': 'abcde...',
...
},
... etc
];
$posts_likes = [
{
'id': 1,
'likeable_type': 'App\Post',
'likeable_id': 2,
'user_id': 3,
...
},
'id': 2,
'likeable_type': 'App\Post',
'likeable_id': 2,
'user_id': 2,
...
{
'id': 3,
'likeable_type': 'App\Post',
'likeable_id': 1,
'user_id': 5,
...
},
{
'id': 4,
'likeable_type': 'App\Post',
'likeable_id': 3,
'user_id': 1,
...
},
... etc
];
My question:
How to insert likes inside $posts collection by matching exact id? (post id == like likeable_id)
So I can access them in loop, like: $post->likes = [...]
Ex:
$posts = [
{
'id': 1,
'user_id': 2,
'body': 'Lorem ipsum...',
'likes': [
// All likes for post with this id (1)
],
...
},
{
'id': 2,
'user_id': 2,
'body': 'Sit amet...',
'likes': [
// All likes for post with this id (2)
],
...
},
...
];
If there's any unclear explanation, I will edit it a.s.a.p Thanks in advance
you can eagar load all of them
ref link https://laravel.com/docs/8.x/eloquent-relationships#nested-eager-loading
$users = User::with('posts.likes')->get();
return $users;
this code will work if you set correct relationship
//user model
public function posts()
{
return $this->hasMany(Post::class, 'user_id', 'id');
}
//post model
public function likes()
{
return $this->morphMany('likeable');
}
i suppose to generate json link
[{
"name": "user",
"posts": [{
"name": "postName",
"likes": []
},
{
"name": "postName",
"likes": []
}
]
}]