假设我有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;
我不知道如何解决这个问题以及究竟是什么问题。
答案 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_key
和other_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'];
}