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

时间:2017-05-09 06:28:40

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

另一方面,有一个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');
        }

}

正如您所看到的,这些之间存在hasMany关系。

用户模型中有full_name个访问者。

现在,我想为teacher_name模型添加一个Course访问者,该模型使用teacher关系并获取教师full_name并始终追加到Course

事实上,我希望无论何时调用Course模型,都会像其他属性一样包含相关的教师名称。

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

exception 'ErrorException' with message 'Trying to get property of non-object' in D:\wamp\www\lms-api\app\Course.php:166

指的是这一课程模型:

$this->attributes['teacher_name'] = $this->teacher()->first()->full_name;

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

6 个答案:

答案 0 :(得分:1)

$this->attributes['teacher_name'] = $this->teacher()->first()->full_name;

应该是

$this->attributes['teacher_name'] = $this->teacher->full_name;

首先,您要引用该关系,因此请忽略括号(),并且因为关系为belongsTo,您将返回一个用户/教师。所以你不需要first()

我们还没有看到你的领域,但可能你必须改变:

return $this->belongsTo('App\User', 'teacher', 'user_id');

return $this->belongsTo('App\User', 'foreign_key', 'other_key');

其中foreign_keyother_key是您加入联系所需的主要密钥。

从文档中查看此链接以供参考: https://laravel.com/docs/5.4/eloquent-relationships#one-to-many-inverse

答案 1 :(得分:0)

正确的方法是:

<强> COURSE

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

答案 2 :(得分:0)

此错误仅是数组使用的对象数据或对象数据使用的数组数据。

示例:

$ var-&gt; feild $ var [feild]

$ var [feild]投入$ var-&gt; feild

答案 3 :(得分:0)

在这里喜欢一些有趣的答案。

对于在我后面的人来说,

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

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

值得阅读attribute accessors/mutators上的laravel文档以获取更多信息。

此外,如果您需要从模型内部访问相关对象(如访问器),则应调用$related = $this->getRelation('foo');-请注意,如果未加载该关系(例如,如果您未获取此对象,集合(具有急切的加载关系),则$this->getRelation()可能返回null,但至关重要的是,如果加载了它,它将不会运行相同的查询来再次获取数据。因此,将其与if (!$this->relationLoaded('foo')) { $this->loadRelation('foo'); }结合使用。然后,您可以照常与相关的对象/集合进行交互。

答案 4 :(得分:0)

您应该使用return作为访问器。像这样的东西:

 public function getTeacherNameAttribute ()
    {
        return $this->teacher()->first()->full_name ?? '';
    }

也许一门课程没有老师。

答案 5 :(得分:0)

100% 为我工作。

我在 Order 和 Shipment 之间建立了一对一的关系。我必须添加订单表中货件表列的访问器。

function getOrderNoAttribute()
    {

        $appendText = "OR100";

        if($this->orderShipment()->first()) {
            $appendText = $this->orderShipment()->first()->is_shipping === 1 ? "ORE100" : "OR100";
        }

        return $appendText . $this->attributes['id'];

    }