Yeasir Arafat
Yeasir Arafat

Reputation: 2191

Paginate laravel query result

I have two models:

  1. User
  2. Post
  3. Comment

User has many posts. Post has many comments and Comment belongs to a Post. That is simple.

Now I want to load all the post of authenticated user with its comments if the post has comment created today. If the post doesn't have comment today, it will not be loaded. The posts will also be paginated. How to build the query in laravel eloquent?

I tried something like this:

Auth::user()->posts->load(['comments' => function($query) {
                $query->where('created_at',Carbon::today());
            }]);

Upvotes: 0

Views: 201

Answers (1)

Kenny Horna
Kenny Horna

Reputation: 14281

The issue in your query is that you are already executing it. Check this part:

Auth::user()->posts->...
            ^^^^^^^^

You are accessing the relationship as a property. When you do that the query is already being executed. What you need to do is to limit the results before executing the query. To do that, access the relationship but as a function, this way you receive an instance of the Query Builder to apply all your constrains before executing the query (with ->get() in this example). To limit a relationship with conditions, you can make use of the whereHas():

$posts = Auth::user()->posts()->whereHas(['comments' => function($query) {
        $query->where('created_at', '>=', today());
    }])
    ->get();

In the above code, you'll receive all the posts that has at least one comment today. But you are yet to receive the comments attached to them. To do so, you need to eager load the relationship with the with() method.

$posts = Auth::user()->posts()->whereHas('comments', function($query) {
        $query->where('created_at', '>=', today());
    })
    ->with('comments') // <--
    ->get();

That should do it. But given that you need the elements paginated, exchange the get() with paginate() method:

$posts = Auth::user()->posts()->whereHas('comments', function($query) {
        $query->where('created_at', '>=', today());
    })
    ->with('comments')
    ->paginate(15); // <---

Upvotes: 2

Related Questions