I am calling an array of all the comments of a poll by using the following code:
$poll = Poll::find($id);
return view('pages.poll', ['poll' => $poll, 'comments' => $poll->comments]);
and the links between Comments and Polls are the following:
Comment.php
public function poll() {
return $this->belongsTo(Poll::class, 'poll_id');
}
Poll.php
public function comments() {
return $this->hasMany(Comment::class, 'poll_id');
}
Finally, I would like to sort the array comments
coming from $poll->comment
by the column likes
in the Comment table, something like DB::table('comment')->orderBy('likes')->get();
.
Is there any way to do that?
CodePudding user response:
There's a number of ways you can do this.
- Add
orderBy('likes')
directly to yourcomments
relationship:
Poll.php
:
public function comments() {
return $this->hasMany(Comment::class, 'poll_id')->orderBy('likes');
}
Now, any time you access $poll->comments
, they will be automatically sorted by the likes
column. This is useful if you always want comments
in this order (and it can still be overridden using the approaches below)
- "Eager Load"
comments
with the correct order:
In your Controller:
$poll = Poll::with(['comments' => function ($query) {
return $query->orderBy('likes');
})->find($id);
return view('pages.poll', [
'poll' => $poll,
'comments' => $poll->comments
]);
with(['comments' => function ($query) { ... }])
adjusts the subquery used to load comments
and applies the ordering for this instance only. Note: Eager Loading for a single record generally isn't necessary, but can be useful as you don't need to define an extra variable, don't need to use load
, etc.
- Manually Load
comments
with the correct order:
In your Controller:
$poll = Poll::find($id);
$comments = $poll->comments()->orderBy('likes')->get();
return view('pages.poll', [
'poll' => $poll,
'comments' => $comments
]);
Similar to eager loading, but assigned to its own variable.
- Use
sortBy('likes')
:
In your Controller:
$poll = Poll::find($id);
return view('pages.poll', [
'poll' => $poll,
'comments' => $poll->comments->sortBy('likes')
]);
Similar to the above approaches, but uses PHP's sorting instead of database-level sorting, which can be significantly less efficient depending on the number of rows.
https://laravel.com/docs/9.x/eloquent-relationships#eager-loading
https://laravel.com/docs/9.x/eloquent-relationships#constraining-eager-loads
https://laravel.com/docs/9.x/collections#method-sortby
https://laravel.com/docs/9.x/collections#method-sortbydesc
CodePudding user response:
$poll->comments->sortBy('likes')