Like we can eager load a relationship of an Eloquent model, is there any way to eager load a method which is not a relationship method of the Eloquent model?
For example, I have an Eloquent model GradeReport
and it has the following method:
public function totalScore()
{
return $scores = DB::table('grade_report_scores')->where('grade_report_id', $this->id)->sum('score');
}
Now I am getting a collection of GradeReport
Eloquent models.
$gradeReports = GradeReport::where('student_id', $studentId)->get();
How can I eager load the returning values of totalScore
method for all GradeReport
Eloquent models in the collection?
You can add arbitrary properties to your models by adding them to $appends array and providing a getter. In your case the following should do the trick:
class GradeReport extends Model {
protected $appends = ['totalScore'];
public function getTotalScoreAttribute() {
return $scores = DB::table('grade_report_scores')->where('grade_report_id', $this->id)->sum('score');
}
}
Now all GradeReport objects returned from your controllers will have totalScore attribute set.
The table grade_report_scores
would also have an eloquent model xyz on which you define a relationship, query scopes, functions, etc.
Add relationship into GradeReport model:
public function scores()
{
return $this->hasMany('xyz', 'grade_report_id', 'id');
}
Now you can rewrite your totalScore
function into this:
public function totalScores()
{
return $this->with(['scores' => function ($query) {
$query->sum('score');
}])->get();
}
not tested, note the closure, there bight be a need to call $query->select('id', 'srore', 'other used values');