Skip to content

新版本 Laravel Eloquent 关联模型 使用技巧

「这是我参与11月更文挑战的第9天,活动详情查看:2021最后一次更文挑战

天下武功没有高下之分,只是习武之人有强弱之别。

上一篇介绍了 Laravel Eloquent 关联模型 进阶使用技巧 ,这篇介绍新版本Laravel的使用技巧,介绍一些简单优雅的新特性。

新版本使用技巧

whereHas 更简洁实现方式

在 Laravel 8.57 中发布:使用 whereRelation() 方法来简写 whereHas()

以前

bash
User::whereHas('articles', function ($query) {     $query->where('published_at', '>', now()); })->get();

现在

css
User::whereRelation('articles', 'published_at', '>', now())->get();

Laravel 7+ 的外键

从 Laravel 7 开始,我们不需要在迁移(migration)中为一些关系字段写两行代码: 一行写字段,一行写外键。

我们可以使用 foreignId() 方法。

Laravel 7 之前

sql
Schema::table('articles', function (Blueprint $table)) {     $table->unsignedBigInteger('user_id');     $table->foreign('user_id')->references('id')->on('users'); }

从 Laravel 7 开始

javascript
Schema::table('articles', function (Blueprint $table)) {     $table->foreignId('user_id')->constrained(); }

当我们的字段不同于表中的引用的情况,可以这么处理:

javascript
Schema::table('articles', function (Blueprint $table)) {     //外键字段是 created_by_id                        关联的是 users 表的 某个字段名称     $table->foreignId('created_by_id')->constrained('users', 'column_name'); }

下面是通用版本技巧

两种 「whereHas」 组合使用

在 Eloquent 中,我们可以在同一条语句中使用 whereHas()orDoesntHave()

举个栗子:

scss
User::whereHas('jobs', function($query) {     $query->where('id', 1); }) ->orDoesntHave('jobs') ->get();

检查关系方法是否已经存在

Laravel中 Eloquent 关系名是支持动态的

我们可以使用这个 PHP 方法 method_exists($object, $methodName) 来检查项目中是否存在相同名称的关系;

注意:一定要做这个检查,否则会导致难以预料,很难定位的问题。

ruby
$user = User::first(); if (method_exists($user, 'jobs')) {     // 使用 $user->jobs()-> 做其它事情... }

获取中间表中的关联关系数据

在多对多关系中,我们定义的中间表里面可能会包含扩展字段,甚至可能包含其它的关联关系。

下面生成一个中间表模型:

go
php artisan make:model JobUser --pivot

然后,给 belongsToMany() 指定 ->using() 方法。

  • app/Models/User.php
kotlin
public function jobs() {     return $this->belongsToMany(Job::class)         ->using(JobUser::class)         ->withPivot(['company_id']); }
  • app/Models/RoleUser.php

注意继承的是 Pivot, 不是 Model

scala
use Illuminate\Database\Eloquent\Relations\Pivot; class JobUser extends Pivot {     public function company()     {         return $this->belongsTo(Conpany::class);     } }

在控制器里面我们可以直接使用如下方式获取中间表 JobUser 的 Company 信息:

scss
$firstCompany = auth()->user()->jobs()->first()->pivot->company->name;

对关联模型数据进行随机排序

我们可以使用 inRandomOrder() 对 Eloquent 的查询结果进行随机排序

同样也可以作用于关联关系中,实现关联数据的随机排序。

scss
// 1. 获取随机用户: $users = User::inRandomOrder()->get(); // 2. 获取随机用户的随机工作: $users = User::with(['jobs' => function($q) {     $q->inRandomOrder(); }])->inRandomOrder()->get();

Last but not least

技术交流群请到 这里来。 或者添加我的微信 wangzhongyang0601 ,一起学习。

感谢大家的点赞、评论、关注,谢谢大佬们的支持,感谢。

🚀 学习遇到瓶颈?想进大厂?

看完这篇技术文章,如果还是觉得不够系统,或者想在实战中快速提升?
王中阳的就业陪跑训练营,提供定制化学习路线 + 企业级实战项目 + 简历优化 + 模拟面试。

了解训练营详情