NOTE Please do not suggest using Eloquent, this is specifically for the Laravel query builder.
For performance reasons we are using Query Builder to retrieve results from a table:
DB::table('posts')->get();
If we then want to join a relation onto that query:
DB:table('posts')
->leftJoin('comments', 'posts.id', '=', 'comments.post_id')
->get();
The results are merged into the array of each post:
[
'id' => 1,
'title' => 'My Blog Post',
'content' => '<h1>This is a post</h1><p>hello world</p>',
'post_author' => 'Billy',
'comment' => 'This is a comment',
'comment_author' => 'Andrew',
]
How can we have the joined results placed into a nested array? Such as:
[
'id' => 1,
'title' => 'My Blog Post',
'content' => '<h1>This is a post</h1><p>hello world</p>',
'post_author' => 'Billy',
'comment' => [
'id' => 22,
'comment' => 'This is a comment',
'comment_author' => 'Andrew',
],
]
Dont think its doable out of the box without Eloquent.
You can go the primitive route:
$results = DB:table('posts')
->leftJoin('comments', 'posts.id', '=', 'comments.post_id')
->select('posts.*', 'comments.*', 'comments.id as comments_id')
->get();
foreach($results as &$result)
{
$result['comment'] = [
'id' => $result['comment_id'],
'comment' => $result['comment'],
'comment_author' => $result['comment_author']
];
unset($result['comment_author'], $result['comment_id']);
}
Since you work with DB facade and not Eloquent, and cannot use built-in with()
method, you have to implement it yourself:
$posts = DB::table('posts')->get()->toArray();
$comments = DB::table('comments')->get()->toArray();
foreach($posts as &$post)
{
$post->comments = array_filter($comments, function($comment) use ($post) {
return $comment->post_id === $post->id;
});
}
return $posts;
If you want to get rid of post_id
for comments entries, you can do:
$posts = DB::table('posts')->get()->toArray();
$comments = DB::table('comments')->get()->toArray();
foreach($posts as &$post)
{
$comments = array_filter($comments, function($comment) use ($post) {
return $comment->post_id === $post->id;
});
$post->comments = array_map(function ($comment) {
unset($comment->id);
return $comment;
}, $comments);
}
return $posts;
(I guess the runtime would be similar to with()
, since after-all MySql does not provide this functionality out-of-the-box).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With