在 Laravel 的模型访问器中使用关系

A.B*_*per 4 php laravel laravel-5.4

假设我有一个Course这样的模型:

class Course extends Model
{    
        public $primaryKey = 'course_id';

        protected $appends  = ['teacher_name'];

        public function getTeacherNameAttribute ()
        {
            $this->attributes['teacher_name'] = $this->teacher()->first()->full_name;
        }

        public function teacher ()
        {
            return $this->belongsTo('App\User', 'teacher', 'user_id');
        }
}
Run Code Online (Sandbox Code Playgroud)

另一方面,有一个User这样的模型:

class User extends Authenticatable
{

        public $primaryKey = 'user_id';

        protected $appends = ['full_name'];

        public function getFullNameAttribute ()
        {
            return $this->name . ' ' . $this->family;
        }

        public function course ()
        {
            return $this->hasMany('App\Course', 'teacher', 'user_id');
        }

}
Run Code Online (Sandbox Code Playgroud)

如您所见,hasMany它们之间存在关系。

full_nameUser 模型中有一个访问器。

现在我想向模型添加一个teacher_name访问器,该Course模型使用它的teacher关系并获取full_name老师并附加到Course始终。

事实上,我希望每当调用一个Course模型时,它与其他属性一样包含相关的教师名称。

但是每次调用 Course 模型时,我都会收到此错误:

exception 'ErrorException' with message 'Trying to get property of non-object' in D:\wamp\www\lms-api\app\Course.php:166
Run Code Online (Sandbox Code Playgroud)

那是指这一行 Course 模型:

$this->attributes['teacher_name'] = $this->teacher()->first()->full_name;
Run Code Online (Sandbox Code Playgroud)

我不知道我该如何解决这个问题以及究竟是什么问题。

Har*_*wis 6

嗯,这里有一些有趣的答案。

仅供参考 -getFooAttribute()应该返回数据,而不是修改内部属性数组。

如果您在属性数组中设置一个新值(在此模型的 db 架构中不存在),然后尝试保存模型,您将遇到查询异常。

值得阅读有关属性访问器/修改器的 laravel 文档以获取更多信息。

此外,如果您需要从模型中访问相关对象(例如在访问器中),您应该调用$related = $this->getRelation('foo');- 请注意,如果未加载关系(例如,如果您没有使用预先加载的关系获取此对象/集合),则$this->getRelation()可以返回 null,但至关重要的是,如果它被加载,它将不会运行相同的查询来再次获取数据。所以与if (!$this->relationLoaded('foo')) { $this->loadRelation('foo'); }. 然后,您可以像往常一样与相关的对象/集合进行交互。