You are calling two relationships on top of each other
Why not delete using foreign keys instead? https://laravel.com/docs/8.x/migrations#foreign-key-constraints
Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.
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');
You are calling two relationships on top of each other
Why not delete using foreign keys instead? https://laravel.com/docs/8.x/migrations#foreign-key-constraints
@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.
@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 :)
@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
@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');
@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 You need to actually add the column to the database using a migration :)
https://laravel.com/docs/8.x/migrations#column-method-softDeletes
@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 Show your current code please.
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.
@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
@Sinnbeck On first line $course->sections->each->lessons()->delete(); / Method Illuminate\Database\Eloquent\Collection::delete does not exist.
@spAo Weird that it returns a collection there.
What does this give you?
dd($course->sections->each->lessons());
@Sinnbeck #items: [] #escapeWhenCastingToString: false
@spAo Can you show the lessons() relationship on the Section model?
public function lessons()
{
return $this->hasMany(Lesson::class, 'section_id', 'id');
}
@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 :)
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');
@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 Check the queries being run using debugbar or clockwork
@Sinnbeck I really don't know how to do it : (
@spAo Install this: https://github.com/barryvdh/laravel-debugbar
Then when it has been installed, you submit the delete request and check the "Queries" tab in debug bar (it is at the bottom of the page)
@Sinnbeck I installed it and then php artisan vendor:publish --provider="Barryvdh\Debugbar\ServiceProvider" but i can't see it in bottom : /
@spAo Be sure that your app is in debug mode
The Debugbar will be enabled when APP_DEBUG is true.
@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
@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
@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;
@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
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
@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();
@Sinnbeck I'm getting 0 on $course->sections()->delete(); and null on $course->delete()
@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.
@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
@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
@Sinnbeck Okay. I will figure it out thanks for response : )
@spAo perhaps make a test route in web.php where you can test it out by just calling the page in the browser
@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
@spAo are you sure you are injecting a model instance?
dd($course->id);
@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 now it all makes sense. Show the route definition
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>
@spAo change this and the old examples should suddenly work
Route::delete('/course/remove/{course}', [CourseManagementController::class, 'courseDestroy'])->name('course.destroy');
@Sinnbeck Alleluia, It worked )) lol thanks a lot for helping : ) <3
@spAo happy to help :)
Please or to participate in this conversation.