Laravel eloquent query loads hundreds of models

Viewed 819

I'm querying a relationship with pagination, yet in my debugbar I can see that all models are loaded in memory and if I'm correct that should not be happening.

I have a Post model with a hasMany relationship to Comments. I have a few lines of code as below. They are written in this order because there are parameters in between that I need to apply. I have shown filterScore here but there are multiple that work the same way.

$post = Post::find(1);
$comments = $post->comments();
$comments = $comment->filterScore($comments)
$comments = $comments->orderBy('created_at', 'DESC');
return $comments->paginate(25);

private function filterScore($q)
{
    if($this->score > 0)
        return $q->where('score', $this->score);

    return $q;
}

The raw query if $this->score = 0:

select * from `comments` where `comments`.`post_id` = 1 and `comments`.`post_id` is not null order by `created_at` desc limit 25 offset 0

UPDATE

I've tried writing it like this, based on this post, but then I still get the same result: all models are loaded into memory.

$post = Post::find(1);
$comments = Comment::query();
$comments = Comment::where('post_id', $post->id);
$comments = $comment->filterScore($comments);
return $comments->paginate(25);

In the Laravel debugbar you can see that all models are loaded into memory, instead of just 25:

enter image description here

1 Answers

One solution is, as @nikistag wrote in comment: $post->comments()->orderBy('created at' , 'DESC')->paginate(25); (you have to have all in one chained expression).

But if you use optional parameters, it can be difficult to achieve someting like that. In this case, you can just change it to 2 seperate codes, where you do not use laravel relationship:

$post = Post::find(1);
$comments = Comment::where('post_id', $post->id);

if(!empty($from)) //if set optional parameter, add condition
    $comments->where('created_at', '>=', $from);

$comments->orderBy('created_at', 'desc')->paginate(25);
Related