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

spAo's avatar
Level 1

Removing course and relationship

Hello all! I have courses / sections / lessons and i want to remove it with one click. So i'm trying to do it but it's errors Call to undefined method Illuminate\Database\Eloquent\Relations\HasMany::lessons()

   public function courseDestroy(Course $course)
    {
        $section = $course->sections();
        $section->lessons()->delete();
        $section->delete();
        $course->delete();
        return redirect('/courses');
    }

route:

Route::delete('/course/remove/{id}', [CourseManagementController::class, 'courseDestroy'])->name('course.destroy');
0 likes
44 replies
spAo's avatar
Level 1

@Sinnbeck I can use cascade delete but i think i need something like soft delete so i did this

    public function courseDestroy($id)
    {
        $course = Course::where('id', $id);

        $updateCourse = $course->update([
            'delete' => '1'
        ]);
        
        $section = Section::where('course_id', $course->id);

        $updateSection = $section->update([
            'delete' => '1'
        ]);

        $lesson = Lesson::where('section_id', $section->id)->update([
            'delete' => '1'
        ]);
    }

but i'm getting error Property [id] does not exist on the Eloquent builder instance.

Sinnbeck's avatar

@spAo I didnt suggest adding a delete column. I suggested letting the database do the deleting for you. When you make a foreign key in a migration, you can add ->onDelete('cascade'); which means that if the parent is deleted, then then all of its children are as well :)

spAo's avatar
Level 1

@Sinnbeck yes but cascade will delete from base but i want to save records . i just want to update course/section/lesson delete column to 1 and then i will hide it from web

Sinnbeck's avatar

@spAo I suggest you use soft deletes for that. Then laravel will handle all of the "magic" for you :)

        $course->sections->each->lessons()->delete();
        $section->sections()->delete();
        $course->delete();
        return redirect('/courses');
spAo's avatar
Level 1

@Sinnbeck it's errors Method Illuminate\Database\Eloquent\Collection::delete does not exist. i changed $section to $course because on $section it's red line but it's errors same. about soft delete i just need to add course/section/lesson use Illuminate\Database\Eloquent\SoftDeletes; use SoftDeletes; and it will work ?

spAo's avatar
Level 1

@Sinnbeck I added in course/section/lesson tables $table->softDeletes(); and in models protected $dates = ['deleted_at']; but i'm getting error in destroy function Method Illuminate\Database\Eloquent\Collection::delete does not exist.

spAo's avatar
Level 1
    public function courseDestroy(Course $course)
    {
        $course->sections->each->lessons()->delete();
        $section->sections()->delete();
        $course->delete();
        return redirect('/courses');
    }

I changed $section to $course but error is same.

Sinnbeck's avatar

@spAo Seems I made a mistake

       $course->sections->each->lessons()->delete();
        $course->sections()->delete(); //changed this line
        $course->delete();
        return redirect('/courses');

If it still fails, please tell me which line it is

spAo's avatar
Level 1

@Sinnbeck On first line $course->sections->each->lessons()->delete(); / Method Illuminate\Database\Eloquent\Collection::delete does not exist.

Sinnbeck's avatar

@spAo Weird that it returns a collection there.

What does this give you?

dd($course->sections->each->lessons());
Sinnbeck's avatar

@spAo Can you show the lessons() relationship on the Section model?

spAo's avatar
Level 1

@Sinnbeck

   public function lessons()
    {
        return $this->hasMany(Lesson::class, 'section_id', 'id');
    }
Sinnbeck's avatar

@spAo Weird.. It totally looks like you are running it without ()

dd($course->sections->each->lessons); //this is wrong
dd($course->sections->each->lessons()); //this is correct

I need to think :)

Sinnbeck's avatar

You can try this, but it might be a bit slower

        $course->load('sections.lessons');
        $course->sections->each->lessons->each->delete();
        $course->sections()->delete();
        $course->delete();
        return redirect('/courses');
spAo's avatar
Level 1

@Sinnbeck Now it's redirect's back to courses but it don't deletes it . I'm getting in inspect network payload

_token: 15BmfZaJre6jdVlAFyP2EAvqL6V2nfxFtSiwFfch
_method: DELETE
spAo's avatar
Level 1

@Sinnbeck I installed it and then php artisan vendor:publish --provider="Barryvdh\Debugbar\ServiceProvider" but i can't see it in bottom : /

Sinnbeck's avatar

@spAo Be sure that your app is in debug mode

The Debugbar will be enabled when APP_DEBUG is true.

spAo's avatar
Level 1

@Sinnbeck Okay it's on now but what i must search in Queries ?

courses where user_id = 1 and courses. deleted_at is null i'm getting this in queries

Sinnbeck's avatar

@spAo If you have soft deletes on, then you should be able to find something like this (might not be exactly the same, but it will be an update query)

update sections where course_id = 10 set deleted_at = 2021-12-29
spAo's avatar
Level 1

@Sinnbeck I'm getting only

select * from `courses` where `user_id` = 1 and `courses`.`deleted_at` is null

I have on tables courses/sections/lessons/ $table->softDeletes(); and in models protected $dates = ['deleted_at']; and use HasFactory, SoftDeletes;

Sinnbeck's avatar

@spAo And you are calling the delete route? Maybe you arent seeing the correct url call. Click the small folder icon in the top right corner, and select the delete route from the list. That should give you the correct queries

spAo's avatar
Level 1

@Sinnbeck

select * from `users` where `id` = 1 limit 1
select * from `sections` where `sections`.`course_id` in (0) and `sections`.`deleted_at` is null
update `sections` set `deleted_at` = '2021-12-29 15:16:30', `sections`.`updated_at` = '2021-12-29 15:16:30' where `sections`.`course_id` is null and `sections`.`course_id` is not null and `sections`.`deleted_at` is null
Sinnbeck's avatar

@spAo Hmm. It assumes that the course ID is null..

 `sections`.`course_id` is null

Maybe try one thing at a time and see what works and what doesn't. Start with just this

        $course->sections()->delete();
        $course->delete();
spAo's avatar
Level 1

@Sinnbeck I'm getting 0 on $course->sections()->delete(); and null on $course->delete()

Sinnbeck's avatar

@spAo 0? Are you sure that the course have sections? Check the database. If the sections have a timestamp in the deleted_at column, that means they are deleted already.

spAo's avatar
Level 1

@Sinnbeck This current course have sections and sections have lessons in database in sections table deleted_at is null

Course have 10 sections and lessons have section_id=10 i have 10 sections an last section (10) have 5 lessons

Sinnbeck's avatar

@spAo sorry but they is really hard to debug when I cannot inspect it directly. You should be able to get it to run the right query with that code. Otherwise run a foreach on sections and delete there

1 like
Sinnbeck's avatar

@spAo perhaps make a test route in web.php where you can test it out by just calling the page in the browser

spAo's avatar
Level 1

@Sinnbeck I did with foreach

    public function courseDestroy(Course $course)
    {
        foreach ($course->sections as $section) {
            foreach ($section->lessons as $lesson) {
                $lesson->delete();
            }
            $section->delete();
        }
        $course->delete();
        return redirect('/all-courses');
    }

But it's still don't work : (

Now i'm getting select * from users where id = 1 limit 1

Sinnbeck's avatar

@spAo are you sure you are injecting a model instance?

dd($course->id);
spAo's avatar
Level 1

@Sinnbeck Lol it is null. I added

public function courseDestroy(Course $course, $id)
    {
        dd($id);
        foreach($course->sections as $section){
            foreach($section->lessons as $lesson){
              $lesson->delete();
            }
            $section->delete();
          }
          $course->delete();
        return redirect('/all-courses');
    }

in Id i'm getting course id but how can i use it ? : /

spAo's avatar
Level 1

@Sinnbeck

Route::delete('/course/remove/{id}', [CourseManagementController::class, 'courseDestroy'])->name('course.destroy');

Blade:

      <form action="/course/remove/{{$course->id}}" method="POST">
            @csrf
            @method('DELETE')
            <button type="submit" class="btn btn-danger">Delete</button>
          </form>
Sinnbeck's avatar
Sinnbeck
Best Answer
Level 102

@spAo change this and the old examples should suddenly work

Route::delete('/course/remove/{course}', [CourseManagementController::class, 'courseDestroy'])->name('course.destroy'); 
2 likes
spAo's avatar
Level 1

@Sinnbeck Alleluia, It worked )) lol thanks a lot for helping : ) <3

Please or to participate in this conversation.