Using Query Builder Constraints on Eloquent Relationships
Since all Eloquent relationships also serve as query builders, constraints can be chained onto relationship calls. Imagine you have a course page that displays only the published course lessons. In your controller, you would query the lessons adding a query constraint for only published lessons.
public function show()
{
$course = Course::find(1);
return view('courses.show', [
'course' => $course->lessons()->where('is_published', true)->get(),
]);
}
In the spirit of keeping controllers lean, we can clean up the above code by using
a local query scope. In the Lesson model, add a method named scopePublished
.
// Lesson Model
public function scopePublished($query)
{
return $query->where('is_published', true);
}
Then go to the Course model and add a new method named publishedLessons
.
// Course Model
public function lessons(): HasMany
{
return $this->hasMany(Lesson::class);
}
public function publishedLessons(): HasMany
{
return $this->lessons()->published();
}
Return to the controller and use the new publishedLessons
method.
public function show()
{
$course = Course::find(1);
return view('courses.show', [
'course' => $course->publishedLessons()->get(),
]);
}