Php 如何从相关模型中附加雄辩的属性而不获取模型';什么内容?
我有两个能言善辩的模型:Php 如何从相关模型中附加雄辩的属性而不获取模型';什么内容?,php,mysql,eloquent,Php,Mysql,Eloquent,我有两个能言善辩的模型: EloquentUser 及 它们都与用户id相关 我正在尝试在SharedEvents模型中设置并附加属性,该属性将附加与之共享事件的用户的全名 为了可读性,我只包含类的appends组件 class SharedEvents extends Model { protected $appends = ['fullName']; /** * @return BelongsTo */ public function user() : BelongsTo
EloquentUser
及
它们都与用户id相关
我正在尝试在SharedEvents模型中设置并附加属性,该属性将附加与之共享事件的用户的全名
为了可读性,我只包含类的appends组件
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;
}
不幸的是,当我运行这个程序时,我得到了全名和整个用户模型,而我只需要全名
有没有办法避免附加用户模型的内容?你能试试吗
public function user() : BelongsTo {
return $this->belongsTo('Path\To\EloquentUser', 'shared_with_id', 'user_id')->select('fullName','user_id');
}
在做了一些研究和实验之后,似乎没有办法用雄辩来做到这一点。不幸的是,我最终采用的解决方案是运行一个附加查询
/**
* 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;
}
这感觉就像你在尝试从你的
ellounter
模型中创建列,在你的SharedEvent
模型中创建一等公民。你越来越接近了,但是想想……
在处理关系时,这是一种明确表达的好方法:
假设user\u full\u 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\u full\u name
是一个访问器,则需要选择构成该访问器的所有列(如上所述)EloquentUser
中的user\u id
和SharedEvent
中的shared\u与\u id
)$appends
在这里的EloquentUser
中是必需的,因为您不能在闭包内直接向子查询添加访问者SharedEvent::with('user')->get();
正如您所看到的,它将在SharedEvent
和您的user
关系上执行select*
在处理使用关系的复杂查询时,我注意到的另一件事是,您可以很快到达一个点,感觉您正在与框架抗争。这通常是考虑使用原始SQL简化OT的一个标志。雄辩是强大的,但只是编程工具带中的另一个工具。请记住,您可以使用其他工具。我遇到了相同的问题,我的第一个想法是在获取SharedEvent时显式隐藏(整个)关联模型 在您的情况下,这看起来像:
class SharedEvents extends Model {
protected $appends = ['fullName'];
protected $hidden = ['user'];
...
}
实际上,我决定不这样做,因为我返回了许多其他附加的模型,所以我决定附加整个用户,但我测试了它,它工作了
仅供参考,我不确定这种差异是否是由于较旧版本的Laravel造成的,但Eloquent实际上希望$appends属性在snake case()中:
请注意,属性名称通常在“snake-case”中引用,即使访问器是使用“camel-case”定义的
您能告诉我们调用
getFullNameAttribute()
accessor的代码吗?因此它会通过查询自动调用。我可以展示它,但这是一个非常漂亮的头发查询。我确实尝试过,但不幸的是得到了相同的结果。回答很好,我自己有时也有同样的感觉。我想在这里的确切场景中,我会坚持为这些情况运行额外的查询。我的API的其余部分依赖于一个laravel集合的结果,除了这个特定字段之外,其他一切都可以正常工作。由于你深思熟虑的分析,我将接受你的回答。谢谢你抽出时间!很高兴我能帮忙。这将仍然是一个雄辩的收集,但也许有一些其他细节我错过了。祝你好运你是对的,这将是一个雄辩的集合,我刚才说我确实依赖API。雄辩的关系不仅仅执行连接。事实上,它们总是执行额外的查询。这是雄辩的一大特点。如果您选择使用雄辩,那么您需要学习如何控制这些查询的效率。看看吧,你会开始对雄辩者在幕后的所作所为有一个很好的理解。
class SharedEvents extends Model {
protected $appends = ['fullName'];
protected $hidden = ['user'];
...
}