ChuksAdirije
ChuksAdirije

Reputation: 95

How do I return Eloqent Models instead of an array when using LengthAwarePaginator?

Some Context

I have a page where I need to show a paginated list of posts. Before now, my controller was:

$posts = Post::whereNotNull('published_at')->paginate(10);

return view('index', compact('posts'));

Then in my view index.blade.php I could do something like:

@foreach ($posts as $post)
    <h3 class="mb-4"><a href="{{$post->link}}">{{$post->title}}</a></h3>
@endforeach

Now I need to limit the query to only 50 posts. However, the below code snippet fails since laravel pagination uses limit internally which overrides my own query. So I still get all the posts in the database:

$posts = Post::whereNotNull('published_at')->limit(50)->paginate(10);

return view('index', compact('posts'));

My Problem

So I used the Illuminate\Pagination\LengthAwarePaginator to create a manual paginator. So now my controller looks like:

$page = LengthAwarePaginator::resolveCurrentPage();

$perPage = 10;

$results = Post::whereNotNull('published_at')->limit(50)->get();

$items = array_slice($results->toArray(), ($page - 1) * $perPage, $perPage);

$posts = new LengthAwarePaginator($items, count($results), $perPage, $page);

return view('index', compact('posts'));

My index.blade.php remains the same. But now if I try to visit the page, I get an error like

Trying to get property 'link' of non-object 

It turns out that in my index.blade.php, each $post in $posts is an array instead of an instance of the Post class.

My Question

How can I get each $post in $posts to be an object (an instance of the Post class)? Ideally, I would like the view to work just the way it is without modification.

I appreciate all the efforts.

Upvotes: 0

Views: 593

Answers (1)

miken32
miken32

Reputation: 42710

Laravel's Collection object has many built-in methods to act like an array. Instead of converting your results to an an array and using array_slice:

$items = array_slice($results->toArray(), ($page - 1) * $perPage, $perPage);

You should use the Collection::slice() method.

$items = $results->slice(($page - 1) * $perPage, $perPage);

Upvotes: 1

Related Questions