Laravel Eloquent 关联模型 进阶使用技巧

共 2428字,需浏览 5分钟

 ·

2021-11-14 16:52

Eloquent关联模型进阶技巧

如何修改父级 updated_at

如果我们想更新一条数据同时更新它父级关联的 updated_at 字段 (例如:我们添加一条文章评论,想同时更新文章的 articles.updated_at),只需要在子模型中使用 $touches = ['article']; 属性。

class Comment extends Model
{
protected $touches = ['article'];
}
复制代码

使用 withCount () 统计子关联记录数

如果我们有 hasMany() 的关联,并且我们想统计子关联记录的条数,不要写一个特殊的查询。

例如,如果我们的用户模型上有文章和评论,使用 withCount()

public function index()
{
$users = User::withCount(['articles', 'comments'])->get();
return view('users', compact('users'));
}
复制代码

同时,在 Blade 文件中,我们可以通过使用 {relationship}_count 属性获得这些数量:

@foreach ($users as $user)

{{ $user->name }}
{{ $user->articles_count }}
{{ $user->comments_count }}

@endforeach
复制代码

还可以按照这些统计字段进行排序:

User::withCount('comments')->orderBy('comments_count', 'desc')->get(); 
复制代码

在关联关系中过滤查询

假如我们想加载关联关系的数据,同时需要指定一些限制或者排序的闭包函数。

例如,我们想获取人口最多的前 5 个国家信息,可以按照如下方式实现:

$countries = Country::with(['contries' => function($query) {
$query->orderBy('population', 'desc');
$query->take(5);
}])->get();
复制代码

动态预加载相关模型

我们不仅可以实现对关联模型的实时预加载,还可以根据情况动态设置某些关联关系,需要在模型初始化方法中处理:

class HobbyTag extends Model
{
protected $with = ['hobby'];

public function __construct() {
parent::__construct();
$this->with = ['hobby'];

if (user()->check()) {
$this->with[] = 'user';
}
}
}
复制代码

使用 hasMany 代替 belongsTo

在关联关系中,如果创建子关系的记录中需要用到父关系的 ID

这种情况下使用 hasMany 比使用 belongsTo 更简洁。

比如:

如果 Post -> belongsTo(User), 并且 User -> hasMany(Post)

Post::create([
'user_id' => auth()->id(),
'title' => request()->input('title'),
'post_text' => request()->input('post_text'),
]);
复制代码

可以这样创建:

auth()->user()->posts()->create([
'title' => request()->input('title'),
'post_text' => request()->input('post_text'),
]);
复制代码

自定义 pivot 属性名称

如果我们想要重命名「pivot」并用其他的什么方式来调用关系,我们可以在关系声明中使用 ->as('name') 来为关系取名。

模型 Model:

public function podcasts() {
return $this->belongsToMany('App\Podcast')
->as('subscription')
->withTimestamps();
}
复制代码

控制器 Controller:

$podcasts = $user->podcasts();
foreach ($podcasts as $podcast) {
// instead of $podcast->pivot->created_at ...
echo $podcast->subscription->created_at;
}
复制代码

一行代码更新归属关系

如果有一个 belongsTo() 关系,我们可以只用一条语句中更新 Elquent 关系:

// if Project -> belongsTo(User::class)
$project->user->update(['email' => 'wzy@qq.com']);


作者:王中阳Go
链接:https://juejin.cn/post/7028217116159393828
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。



浏览 25
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报