I have this:
$commentReplies = Comment::whereIn('comment_parent_id', $CommentsIDs)
->take(2)->get();
Where $CommentsIDs
is an array of 3 parent comment ids (1,2,3).
I am trying to retrieve 2 replies for each of the $commentsIDs if they exist. So a total of 6 replies (2 for each comment) should come back with the query, if the replies exist, nothing more. However, with take(2) in there, it limits the replies to 2, and we only get 2 replies for one of the comments. How can it be setup to get 2 replies for each of the comment IDs in the most efficient way, and how can they get rendered in the view with the correct nesting?
Something like:
Comment 1
--Comment 1 Reply 1 (load this)
--Comment 1 Reply 2 (load this)
--Comment 1 Reply 3 (don't load this)
--Comment 1 Reply 4 (don't load this)
Comment 2
--Comment 2 Reply 1 (load this)
--Comment 2 Reply 2 (load this)
--Comment 2 Reply 3 (don't load this)
Comment 3
(no replies, don't load anything)
Update:
Here is the Comment Model:
class Comment extends BaseModel {
public function latestTwoComments()
{
return $this->hasMany('Comment','comment_parent_id')->latest()->nPerGroup('comment_parent_id', 2);
}
}
Query:
$comments = Comment::with('latestTwoComments')->get();
dd(DB::getQueryLog());
// Result:
'query' => string 'select * from (select `comments`.*, @rank := IF(@group = comment_parent_id, @rank+1, 1) as rank_575b053fb57f8fab5bc86dd324b39b91, @group := comment_parent_id as group_575b053fb57f8fab5bc86dd324b39b91 from (SELECT @rank:=0, @group:=0) as vars, comments where `comments`.`deleted_at` is null order by `comment_parent_id` asc, `created_at` desc) as comments where `comments`.`deleted_at` is null and `rank_575b053fb57f8fab5bc86dd324b39b91` <= ? and `comments`.`comment_parent_id` in (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?'... (length=603)
You can't use limit
/skip
when eager loading, for it will limit whole related result.
I suppose you use MySQL, so here is what you need: http://softonsofa.com/tweaking-eloquent-relations-how-to-get-n-related-models-per-parent/
It's way to long to paste here, so just to get the idea: You need MySQL variables to do the job of fetching n per parent for you, like:
public function latestTwoComments()
{
return $this->hasMany('Comment', 'comment_parent_id')->latest()->nPerGroup('comment_parent_id', 2);
}
//then
$comments = Comment::with('latestTwoComments')->get();
// now all the comments will have at most 2 related child-comments
Note: it's meant for hasMany
relation and MySQL
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