Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

Lozza's avatar
Level 4

The best way to access / iterate through a sub-relation

I don't like my code below.. please let me know the correct way to do it :-)

I have the following model Booking with 2 step relationshp to TmpSeatAllocation

Booking:
    public function Tickets() {
        return $this->hasMany(Ticket::class);
    }

Ticket:
    public function TmpSeatAllocation() {
        return $this->hasOne(TmpSeatAllocation::class);
    }

TmpSeatAllocation...

I currently have the following code to retrieve the seat allocations for a booking via the tickets

    $bookings = ModelsBooking::find($booking_id)->with('Tickets.TmpSeatAllocation')->get();

and I iterate through this data as follows:

    for ($ix=0;$ix<$bookings[0]->Tickets->count();$ix++) {
        $this->moveSeatAllocationToLive($bookings[0]->Tickets[$ix]->TmpSeatAllocation);
    }

I would prefer to use a foreach() but struggled to make it work!

0 likes
4 replies
LaryAI's avatar
LaryAI
AI
Best Answer
Level 58

Certainly! You can simplify your iteration by using a nested foreach loop to iterate through the tickets and their associated TmpSeatAllocation. Here's how you can do it:

$booking = Models\Booking::with('Tickets.TmpSeatAllocation')->find($booking_id);

if ($booking) {
    foreach ($booking->Tickets as $ticket) {
        if ($ticket->TmpSeatAllocation) {
            $this->moveSeatAllocationToLive($ticket->TmpSeatAllocation);
        }
    }
}

In this code snippet:

  1. We retrieve the booking with the related tickets and their seat allocations using eager loading.
  2. We check if the booking was found to avoid errors in case the $booking_id does not exist.
  3. We iterate over each ticket associated with the booking using a foreach loop.
  4. Inside the loop, we check if the ticket has an associated TmpSeatAllocation before calling the moveSeatAllocationToLive method.

This approach is cleaner and more readable than using a for loop with index access. It also handles cases where there might be tickets without a TmpSeatAllocation.

1 like
Lozza's avatar
Level 4

Great, that worked!! I think I had a brainf**t when I wrote that code :-D

Snapey's avatar

conventionally, your relationships should all be camel case, eg tickets.tmpSeatAllocation as they are function names not classes.

1 like
Lozza's avatar
Level 4

@Snapey Funny, I had it like that and changed it to match the dd of the eloquent result :-) Thanks for the info!!

Please or to participate in this conversation.