【问题标题】:Laravel - eager loading a method (not a relationship) of an Eloquent modelLaravel - 急切加载 Eloquent 模型的方法(不是关系)
【发布时间】:2017-01-12 01:05:38
【问题描述】:

就像我们可以预先加载 Eloquent 模型的关系一样,有没有什么方法可以预先加载不是 Eloquent 模型的关系方法的方法?

例如,我有一个 Eloquent 模型 GradeReport,它有以下方法:

public function totalScore()
{
    return $scores = DB::table('grade_report_scores')->where('grade_report_id', $this->id)->sum('score');
}

现在我正在收集GradeReport Eloquent 模型。

$gradeReports = GradeReport::where('student_id', $studentId)->get();

如何为集合中的所有 GradeReport Eloquent 模型预先加载 totalScore 方法的返回值?

【问题讨论】:

    标签: php laravel laravel-5 eloquent


    【解决方案1】:

    您可以通过将任意属性添加到 $appends 数组并提供 getter 来为模型添加任意属性。在您的情况下,以下应该可以解决问题:

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

    现在从控制器返回的所有 GradeReport 对象都将设置 totalScore 属性。

    【讨论】:

    • 或许能解决问题,但不是eager loading,每次访问这个model属性都会调用DB
    • 这符合我的预期。但是,我想对属性进行一些小改动以使其看起来更好。 protected $appends = ['total_score'];.
    • @animaacija 它可能不会急于加载,但它可以按我的需要工作。我想在这种情况下不可能预先加载。
    【解决方案2】:

    表grade_report_scores 也将有一个雄辩的模型xyz,您可以在该模型上定义关系、查询范围、函数等。

    将关系添加到 GradeReport 模型中:

    public function scores()
    {
        return $this->hasMany('xyz', 'grade_report_id', 'id');
    }
    

    现在您可以将您的 totalScore 函数重写为:

    public function totalScores()
    {
        return $this->with(['scores' => function ($query) {
            $query->sum('score');
        }])->get();
    }
    

    未测试,注意关闭,可能需要致电$query->select('id', 'srore', 'other used values');

    【讨论】:

      猜你喜欢
      • 2013-06-10
      • 1970-01-01
      • 1970-01-01
      • 2021-11-29
      • 2017-09-30
      • 1970-01-01
      • 1970-01-01
      • 2018-12-11
      • 2017-09-17
      相关资源
      最近更新 更多