Search code examples
laraveleager-loading

Laravel eager loading does not seem to work


See the database relations in the image below. enter image description here

I want to show all the available hours (9 hours per day) of a classroom including the capacity for that hour and the departments allowed for that hour inncluding the subjects which are excluded from the classroom or the subjects for which the classroom is exclusive. In my show.blade.php I build a table and each tablecell shows one availableHour. As this requires two loops, one for the days and one for the hour of the day, I want to eager load the classroom with the relations. But judging by the time it takes the request to complete (almost 2 sec) and the number of queries reported by telescope the database is questioned with or without eager loading.

In my controller I load the relations like this:

$classroom->load('availableHours.allowedDepartments.exclusiveSubjects.subject',
'availableHours.allowedDepartments.excludedSubjects.subject',
'availableHours.allowedDepartments.department');

If I dump the classroom the relations are loaded. In my show.blade.php I loop through the availableHours like this:

<!-- loop through all the hours of the day  -->
    @for($i=1;$i<=$maxHour;$i++)
        <tr>
        <td>
        <a href="/classrooms/{{$classroom->number}}/0/{{$i}}/edit">
            {{$i}}
        </a></td>
        <!-- loop through all the days -->
        @foreach($days as $day)
            <!-- show the available hour either in green (available) or red (unavailable)-->
            <td>
            <a href="/classrooms/{{$classroom->number}}/{{$day->id}}/{{$i}}/edit">
                <!-- show the capacity of the hour of the day-->
                {{ $classroom->availableHours()->where([['day_id','=',$day->id],['hour_of_day',$i]] )->first()->capacity }} <br/>

                @foreach($classroom->availableHours()->where([['day_id','=',$day->id],['hour_of_day',$i]] )->first()->allowedDepartments as $allowedDepartment)
                <!-- show the permitted departments along with any exclusive or excluded subjects-->
                {{$allowedDepartment->department->name}}
                @foreach ($allowedDepartment->exclusiveSubjects as $subjectDepartment)
                    {{$subjectDepartment->subject->code}}
                @endforeach
                 <br/>
                @endforeach
            </a></td>
        @endforeach
        </tr>
    @endfor

As I stated this results in the database being queried again instead of using the preloaded relations. What am I doing wrong?


Solution

  • When you call $classroom->availableHours(), you are actually querying the relation function again and returning it, instead of accessing the one that already exists.

    After you load the relations in the controller, the object is filled with attributes containing the desired values. So after loading, use $classroom->availableHours instead. (like you did with $allowedDepartment->exclusiveSubjects)