我有2个雄辩的模特:
EloquentUser
和
SharedEvents
它们都与user_id
相关我正在尝试在SharedEvents模型中设置和追加属性,该属性将附加已与其共享事件的用户的full_name。
为了便于阅读,我只包括我班级的附加组件
class SharedEvents extends Model {
protected $appends = ['fullName'];
/**
* @return BelongsTo
*/
public function user() : BelongsTo {
return $this->belongsTo('Path\To\EloquentUser', 'shared_with_id', 'user_id');
}
/**
* @return mixed
*/
public function getFullNameAttribute(){
return $this->user->user_full_name;
}
不幸的是,当我运行它时,我只需要全名和整个用户模型,而我只需要全名。
有没有办法避免附加用户模型的内容?
答案 0 :(得分:1)
感觉就像是在尝试使用EloquentUser
模型中的SharedEvent
模型头等公民制作列。你越来越近了,但考虑一下......
在处理关系时,这是明确的好方法:
假设user_full_name
是User
型号的访问者:
// EloquentUser.php
// This will automatically add your accessor to every query
// as long as you select the columns the accessor is made
// up of
protected $appends = ['user_full_name'];
/**
* User Full Name Accessor
* @return string
*/
public function getUserFullNameAttribute()
{
return $this->first_name . ' ' . $this->last_name;
}
// SharedEvent.php
/**
* A SharedEvent belongs to an Eloquent User
* @return BelongsTo
*/
public function user() : BelongsTo
{
return $this->belongsTo('Path\To\EloquentUser', 'shared_with_id', 'user_id');
}
// Somewhere in your controller or wherever you want to access the data
$sharedEvents = SharedEvent::with(['user' => function ($query) {
$query->select('user_id', 'first_name', 'last_name');
}])->where(...)->get(['shared_with_id', ...other columns]); // you must select the related column here
这应该让你最接近你想要的,但你应该知道几件事:
user_full_name
是访问者,则需要选择构成该访问者的所有列(如上所述)user_id
中的EloquentUser
和shared_with_id
中的SharedEvent
)$appends
需要EloquentUser
,因为您无法在闭包内直接添加子查询的访问者。尝试使用闭包作为关系中的第二个参数。这是你在加载关系时选择哪些列的最佳方法 - Eloquent让你很容易变得懒惰而且只是这样做:
SharedEvent::with('user')->get();
正如您所看到的,select *
与您的SharedEvent
关系只会user
。
在处理使用关系的复杂查询时,我注意到的另一件事是,您可以快速达到感觉就像在与框架作斗争的程度。这通常是考虑简化使用原始SQL的标志。 Eloquent功能强大,但它只是编程工具带中的另一个工具。请记住,您可以使用其他工具。
答案 1 :(得分:0)
你能试试吗?
public function user() : BelongsTo {
return $this->belongsTo('Path\To\EloquentUser', 'shared_with_id', 'user_id')->select('fullName','user_id');
}
答案 2 :(得分:0)
在做了一些研究和实验之后,看起来似乎没有办法用Eloquent做到这一点。不幸的是,我最终还是运行了另一个查询。
/**
* This is inefficient, but I could not find a way to get the full name
* attribute without including all of user.
*
* @return string
*/
public function getFullNameAttribute(){
return EloquentUser::select('user_full_name')
->where('user_id', $this->shared_with_id)
->first()
->user_full_name;
}
答案 3 :(得分:0)
我遇到了同样的问题,我的第一个想法是在获取 SharedEvent 时显式隐藏(整个)关联的模型。
在您的情况下,这看起来像:
class SharedEvents extends Model {
protected $appends = ['fullName'];
protected $hidden = ['user'];
...
}
我实际上决定不这样做,因为我要返回许多其他附加模型,所以我决定附加整个用户,但是我对其进行了测试,并且可以正常工作。
仅供参考,我不确定差异是否是由于Laravel的较旧版本引起的,但Eloquent实际上期望$ appends属性采用蛇形(https://laravel.com/docs/5.6/eloquent-serialization#appending-values-to-json):
请注意,即使访问器是使用“驼峰大小写”定义的,属性名称也通常在“蛇形大小写”中引用