加载 hasMany 关系的最后一条记录
Posted
技术标签:
【中文标题】加载 hasMany 关系的最后一条记录【英文标题】:Loading last record of hasMany relationship 【发布时间】:2020-07-16 14:33:12 【问题描述】:我的控制器中有以下代码,我正在尝试加载所有“成员”。每个成员可以拥有多个电话号码。电话号码存储在名为phone_numbers
的表中,并与用户ID 相关联。下面,我正在尝试加载为每个成员存储的最后一个电话号码。请注意,用户在手机上有一个 hasMany 关系。
用户.php
public function phone()
return $this->hasMany('App\Model\PhoneNumber');
这是我尝试过的:
$members = \App\Model\User::all();
$members->load('phone');
感谢任何有关如何完成此任务的建议。
【问题讨论】:
最后一个电话号码是什么意思? 每个用户可以拥有多个电话号码。我的意思是,我想要与每个用户绑定的最新电话号码。 你在表中使用 Laravel 的时间戳属性吗(created_at
和 updated_at
)?
是的,我做了,我已经设置好了
【参考方案1】:
我没有测试它,但你可以这样查询:
$members = User::with(['phone' => function($query)
$query->orderBy('created_at', 'desc')->first();
]);
这会将所有用户返回给您,但连接了手机的用户只会创建最新的记录。
【讨论】:
【参考方案2】:要获取最新的行,你可以使用latest
,并使用hasOne
这样的关系:
public function phone()
return $this->hasOne('App\Model\PhoneNumber')->latest();
因此您可以为所有用户获取最新的手机:
User::with('phone')->get();
【讨论】:
您应该提到with('phone')
在检索模型之前很重要,因为关系的延迟加载。 (我在回答中忘记了)
感谢您的回复。这是干净的。这是否也会让用户没有存储电话号码?
等等,这不起作用。注意,电话是hasMany关系。
@AnchovyLegend 是的,如果你想得到没有电话号码,你可以使用whereHas
方法。你可以定义hasMany phones
和hasOne phone
不,我希望它包括所有有和没有电话号码的用户,并在可用时获取电话号码。所以我可以通过$mebmers->phone_number
获取我认为的最新电话号码。【参考方案3】:
你可以这样做:
在您的用户模型中:
/**
* The accessors to append to the model's array form.
*
* @var array
*/
protected $appends = ['last_phone'];
protected function getLastPhoneAttribute()
return $this->phone()->orderBy('created_at')->first();
use App\Model\User;
$lastPhones = User::all()->map->last_phone;
【讨论】:
我想将它添加到我要注入的成员数据中吗?所以我可以做$member->phone_numeber
?
注意,这不起作用。我将 $appends 设置为电话号码的实际字段名称,即phone_number
,在我的控制器中我这样做了:$members = User::all()->map->phone_number; dd($members);
所有电话号码都回来了null
。
小心访问器,这意味着每次查询这个用户模型,都会加载手机
last_phone
是一个虚拟属性,$appends
属性告诉 Laravel 将它附加到每个模型上。
您已经在 laravel.com/docs/7.x/eloquent-mutators 和 map
laravel.com/docs/7.x/collections#higher-order-messages 中解释了所有内容以上是关于加载 hasMany 关系的最后一条记录的主要内容,如果未能解决你的问题,请参考以下文章
用于从 hasMany 关系中检索一条记录的 Ember 计算属性?
Ember Mirage 模型:对于多个 hasMany 和 belongsTo
Laravel 关系查询加载 hasMany + BelongsToMany
Ember.js:重新加载通过有效负载中的“链接”给出的 .hasMany 关系