user11124425
user11124425

Reputation: 971

Eloquent ID & Foreign key

My table Cous has a column date_seance with 2 recordings.

enter image description here

In my table Retour, I have to retrieve the date_seance.

enter image description here

Except that, I always retrieve the same value. Where is the 23/10/2019 one?

In my model Cous I have this:

public function retours()
    {
        return $this->hasManyThrough(
            'App\Retour',
            'App\Eleve',
            'fk_cours', 
            'fk_eleve',
            'id', 
            'id' 
        );
    }

In my Retour index.blade.php I have this:

 @foreach($retours as $retour)
 <tr>
    <td> {{$retour->instruction}}</td>
    <td> {{$retour->description}}</td>
    <td> {{$retour->eleves->nom}}</td>  
    <td> {{$retour->eleves->prenom}}</td>  
    <td> {{$retour->eleves()->first()->cours()->first()->date_seance->format('d/m/Y')}}</td>
    <td> {{$retour->eleves()->first()->cours()->first()->moniteurs->nom}}</td>
    <td> {{$retour->eleves()->first()->cours()->first()->moniteurs->prenom}}</td>
    <td> {{$retour->eleves()->first()->paiements()->first()->date_saisie->format('d/m/Y')}}</td> 

My problem is this line:

<td> {{ $retour->eleves()->first()->cours()->first()->date_seance->format('d/m/Y') }}</td>

I don't understand my problem.

I thank you in advance for your help.

Upvotes: 0

Views: 86

Answers (1)

Watercayman
Watercayman

Reputation: 8178

A couple of things to mention. First, calling your eleves relationship on your blade form like this:

$retour->eleves()

is going to go back to the database on every single call. This could add up to a lot of delay if you have a lot of retour objects, or even if you just go through that table.

Strongly recommend eager loading as much as you can on at least the retour collection.

On your controller:

// Not sure if you had any constraints, but this will eager load eleves
$retours = Retour::with('eleves')->get();  

The issue with your always pulling the same date is that you are possibly pulling from the same object. I love a good chain... but sometimes longer chains become more confusing than they are worth. Take a look at this line:

$retour->eleves()->first()->cours()->first()->date_seance

If you break this down from just the first loop on your blade page, you are pulling the first eleves from this first retour object from the overall collection of retour objects. Then, you are pulling the first cours object from that first eleves from that first retour object. The reason the date is the same is that you are possibly pulling the same cours object. I say possibly because the first() method is just pulling the first instance associated with the retour object in the database. Not the latest, just the first. So, if there are multiple eleves for every retour, if the one with say id of 1 is attached to both the first and the second retour, you are pulling the same exact eleves in the second loop. This is further compounded by exactly the same issue on the cours relationship with eleves. If you have say a cours with id of 21 attached to multiple eleves, you might be pulling the exact same cours even though you are on a totally different loop for both retour and eleves.

To fix this, you need to have a solid handle on which eleves and which cours objects you are referring to in your loop. I would recommend not querying at the top level (retours), but rather, having a couple of lower level queries on those relationships (eleves or cours) and loop directly on those in your blade.

E.g. in your Controller:

$courses = Cours::where('some constraint', $someConstrainer)->get()

Then, in your blade, just loop on the $courses collection:

@foreach($courses as $cours){
    // Other stuff here...
    <td> {{ $cours->first()->date_seance->format('d/m/Y') }}</td>

If you can't do it at the cours level, perhaps back out one level higher and load with eleves (while eager loading the cours objects).

Upvotes: 1

Related Questions