johnnerle's avatar

Paginate also the many side of relation

How do I paginate also the the many side of a HasMany relation, for example DeviceType::with('devices')->paginate(10)

limits only DeviceType but fetches all related devices

0 likes
6 replies
LaryAI's avatar
Level 58

To paginate both the DeviceType and its related devices, you need to handle pagination separately for each. The paginate method in Eloquent only applies to the main query, not the related models. Here's how you can achieve pagination for both:

  1. Paginate the DeviceType models: Use the paginate method on the DeviceType model.

  2. Paginate the devices for each DeviceType: Use the paginate method on the devices relationship within a loop.

Here's an example of how you can implement this:

use App\Models\DeviceType;

$deviceTypes = DeviceType::paginate(10);

foreach ($deviceTypes as $deviceType) {
    // Paginate the devices for each DeviceType
    $deviceType->devices = $deviceType->devices()->paginate(5);
}

// Now you can pass $deviceTypes to your view

In this example, DeviceType::paginate(10) paginates the DeviceType models, and for each DeviceType, we paginate the devices with ->paginate(5). Adjust the pagination numbers as needed for your application.

In your view, you can then iterate over $deviceTypes and for each DeviceType, iterate over the paginated devices. This way, both the DeviceType and its related devices are paginated.

johnnerle's avatar

yeah ... this works but how do I acces the links for devices in the blade view??

$devices()->links() gives an error

shariff's avatar

Did you try like this

example

    $deviceTypes = DeviceType::paginate(10);
    $deviceTypes->getCollection()->transform(function ($deviceType) {
        $deviceType->devices = $deviceType->devices()->paginate(10);
        return $deviceType;
    });

In views

@foreach ($deviceTypes as $deviceType)
    <h2>{{ $deviceType->name }}</h2>

    @foreach ($deviceType->devices as $device)
        <p>{{ $device->name }}</p>
    @endforeach

    {{ $deviceType->devices->links() }}
@endforeach

{{ $deviceTypes->links() }}

1 like
jlrdw's avatar

I double paginate.

For example if I have a list of companies with their payables I set up a link for next company and under the companies I have their payables paginated.

I usually don't bother using eloquent for such things I prefer regular queries with getPdo() and a custom length-aware-paginator.

1 like
Thunderson's avatar

I don't understand why you need all this data at once. sometimes if laravel doesn't directly allow you to do something it means that your design is too atypical and often it means you are going about it in the wrong way. i think it is a UI problem. First load all the device types in a paginated list in an html table,

DeviceType::paginate(10);

then for each line you can put a button which allows you to load all different linked devices using the id of the device type that way:

Device::where('type_id',$id)->paginate(10);

then display these paginated data in modal window or a side of the page. of course you will use a little js to make it work. now your frontend will be more efficient

Please or to participate in this conversation.