NoLAstNamE's avatar

Paginating data in nested foreach loop

I have a User model that has a hasMany relationship to Flight model, and I am showing the users with their flights on one page.

I'm having a problem with how can I paginate the users and also paginate the flights that a user has.

If we add pagination for each of the flights of the user isn't there a conflict in the URL because the system doesn't know which user flights to paginate?

I mean after clicking the next page of pagination inside the user's flights it will affect the main pagination of users.

Controller

public function usersWithFlights() {
    $users = User::with('flights')->withCount('flights')->paginate(20);
}

Blade view

@forelse ($users as $key => $user)
    <h3>{{ $user->name }}</h3>
    <hr>
    <table class="table table-hover table-bordered">
        <thead>
            <tr>
                <th>From</th>
                <th>To</th>
            </tr>
        </thead>
        <tbody>
            @foreach($user->flights as $flight)
                <tr>
                    <td>{{ $flight->origin }}</td>
                    <td>{{ $flight->destination }}</td>
                </tr>
            @endforeach
            // How to paginate flights here?
        </tbody>
    </table>
@empty
    No data .
@endforelse

// paginate users here
{{ $users->links() }}
0 likes
12 replies
Sinnbeck's avatar

How would that work for the user on the page? If I want to see page 3 on a certain users flights, you expect it to remember flight page separately for each user/flight ?

1 like
NoLAstNamE's avatar

@Sinnbeck Yes, I still want to persist the current page of the users after clicking the pagination of user flights.

e.g.

I'm on page 1 of the user's list and I click page 2 of the flights for User A, the expected result is I'm still on page 1 but on page 2 of the flights of User A.

Sinnbeck's avatar

@benjamin1509 Ok I cannot see any way to get that working. You would need to set up pagination for every single user on the page. Maybe doing it with ajax would be best then :)

1 like
NoLAstNamE's avatar

@Sinnbeck I don't know if you know this one but I tried this answer from SO and it worked!

This produces this URL: http://example.test/users?users=1&flights=2

Controller

$users = User::with('flights')->withCount('flights')->paginate(20, ['*'], 'users')->withQueryString();

Blade

@php
    $userFlights = $user->flights->paginate(1, ['*'], 'flights')->withQueryString();
@endphp

@foreach($userFlights as $flight)
    <tr>
        <td>{{ $flight->origin }}</td>
        <td>{{ $flight->destination }}</td>
    </tr>
@endforeach

{{ $userFlights->links() }}
Sinnbeck's avatar

@benjamin1509 From just looking at it, it would seem to change all users flights when you change 1?

1 like
Sinnbeck's avatar
Sinnbeck
Best Answer
Level 102

@benjamin1509 You could try this

@php
    $userFlights = $user->flights->paginate(1, ['*'], 'flights' . $user->id)->withQueryString();
@endphp
1 like
Sinnbeck's avatar

But I dont see why this does not throw an error

$user->flights->paginate()

As far as I know collections does not have a paginate method. Any change flights is a hasOne relationship? Can you show it ?

1 like
NoLAstNamE's avatar

@Sinnbeck Oh sorry, I have a typo there, it should be flights()

public function flights(): HasMany
{
    return $this->hasMany(Flight::class);
}

Please or to participate in this conversation.