laraveleloquentlaravel-bladelaravel-controller

How to retrieve Nested Relationship in Laravel View


I'm new to laravel, but learning along the way.. Now I have 3 Tables [ courses, units and lessons ]

Courses has multiple Units and each unit has multiple lessons

Database Tables look something like this :

courses
id
crs_name
..

units
id
course_id
unit_title

lessons
id
course_id
unit_id
lesson_title

Relationships are defined as follows : Unit Model

public function course(){return $this->belongsTo('App\Course');}

Course Model

public function units(){return $this->hasMany('App\Unit');}
public function lessons(){return $this->hasMany('App\Lesson');}

Lesson Model

public function course(){return $this->belongsTo('App\Course');}
public function unit(){return $this->belongsTo('App\Unit');}

This is my Controller [ I'm sure the problem is here as I can't define the nested relationship ]

    public function singleCourse($id)
{ 
    $course = Course::find($id);
    $reviews = Review::where('course_id', $id)->orderBy('created_at', 'desc')->take(30)->paginate(10);
    $lessons = Lesson::where('course_id', $id)->take(15);
    $units = Unit::with('lessons')->where('course_id', $id)->take(15);
    return view('courses.course', compact('course', 'reviews', 'lessons', 'units'));
}

In my View I managed to retrieve the course Units, but can't get lessons of each units and when I try anything else, I get errors enter image description here

My View

@foreach($course->units as $unit)
                      <div class="card">
                        <div class="card-header">
                          <h3 class="accordion-heading">
                            <a href="#shippingOptions" role="button" data-toggle="collapse" aria-expanded="true" aria-controls="shippingOptions">
                              <i class="fas fa-bookmark"></i>
                               {{$unit->unit_title}}<span class="accordion-indicator"></span>
                            </a>
                          </h3>
                        </div>
                        <div class="collapse show" id="shippingOptions" data-parent="#productPanels">
                        @foreach($unit->lessons as $lesson)

                          <div class="card-body font-size-sm">
                            <div class="d-flex justify-content-between border-bottom pb-2">                           
                              <div>
                                <div class="font-weight-semibold text-dark"><i class="czi-video"></i> {{{$lesson->lesson_title}}}</div>
                                <div class="font-size-sm text-muted"><i class="far fa-clock"></i> 1h 20m</div>
                              </div>

                            </div>

                          </div>
                          @endforeach
                        </div>
                      </div>
                      @endforeach

Would really appreciate any help with the controller and View


Solution

  • In your controller, You have to make few changes as with is use when we redirecting to a new URL and flashing data to the session as explained here. So you can replace your controller with given below:

    public function singleCourse($id)
    { 
        $course = Course::with(['lessons', 'units'])->find($id);
        $reviews = Review::where('course_id', $id)->orderBy('created_at', 'desc')->take(30)->paginate(10);
        $lessons = $course->lessons()->take(15);
        $units = $course->units()->take(15);
        return view('courses.course', compact('course', 'reviews', 'lessons', 'units');
    }
    

    To get lessons of unit you have to define a relation in unit model:

    public function lessons()
    {
       return $this->hasMany('App\Lesson');
    }
    

    And to get specific unit lessons you have to do in your blade:

    $unit->lessons
    

    Here your find code for blade file will be :

    @foreach($course->units as $unit)
    <div class="card">
    <div class="card-header">
      <h3 class="accordion-heading">
        <a href="#shippingOptions" role="button" data-toggle="collapse" aria-expanded="true" aria-controls="shippingOptions">
          <i class="fas fa-bookmark"></i>
           {{$unit->unit_title}}<span class="accordion-indicator"></span>
        </a>
      </h3>
    </div>
    <div class="collapse show" id="shippingOptions" data-parent="#productPanels">
    @foreach($unit->lessons as $lesson)
    
      <div class="card-body font-size-sm">
        <div class="d-flex justify-content-between border-bottom pb-2">                           
          <div>
            <div class="font-weight-semibold text-dark"><i class="czi-video"></i> {{{$lesson->lesson_title}}}</div>
            <div class="font-size-sm text-muted"><i class="far fa-clock"></i> 1h 20m</div>
          </div>
    
        </div>
    
      </div>
      @endforeach
    </div>
    </div>
    @endforeach