Laravel - eager loading a method (not a relationsh

2019-03-30 09:43发布

问题:

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?

回答1:

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.



回答2:

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');