模型关联
在 Eloquent 关系中使用 OrderBy
您可以在关联关系中直接指定 orderBy ()。
public function products()
{
return $this->hasMany(Product::class);
}
public function productsByName()
{
return $this->hasMany(Product::class)->orderBy('name');
}在 Eloquent 关系中添加条件
假如你经常在模型关联关系中添加某些相同的 where 条件,可以单独创建一个方法。
Model:
public function comments()
{
return $this->hasMany(Comment::class);
}
public function approved_comments()
{
return $this->hasMany(Comment::class)->where('approved', 1);
}DB 原生查询 havingRaw ()
你可以在很多地方使用原始数据库查询,比如在 groupBy() 后面调用 havingRaw()
Eloquent 使用 has () 实现多层调用查询
你可以在关联关系查询中使用 has() 实现两层关联查询。
一对多关系中获取符合指定数量的信息
在 hasMany() 中,你可以通过条件过滤,获取符合的数据。
默认模型
你可以在 belongsTo 关系中设置返回一个默认的模型,从而避免类似于使用 {{ $post->user->name }} 当 $post->user 不存在的时候,引起的致命的错误
一对多关系中一次创建多条关联数据
在一对多关系中,你可以使用 saveMany 通过一次提交,保存多条关联数据。
多层级预加载
在 Laravel 中,你可以在一条语句中预加载多个层级,在这个例子中,我们不仅加载作者关系,而且还加载作者模型上的国家关系。
预加载特定字段
你可以在 Laravel 中预加载并指定关联中的特定字段。
你同样可以在深层级中这样做,如第二层级关系:
轻松更新父级 updated_at
如果你想更新一条数据同时更新它父级关联的 updated_at 字段 (例如:你添加一条帖子评论,想同时更新帖子的 posts.updated_at),只需要在子模型中使用 $touches = ['post']; 属性。
一直检查关联是否存在
永远不要在不检查关联是否存在时使用 $model->relationship->field 它可能因为任何原因,如在你的代码之外,被别人的队列任务等等被删除。
用 if-else,或者在 Blade 模板中 {{$model->relationship->field ? ? '' }},或者 {{optional($model->relationship)->field }} 。在 php8 中,你甚至可以使用 null 安全操作符 {{ $model->relationship?->field) }}
使用 withCount () 来统计关联记录数
如果你有 hasMany() 的关联,并且你想统计子关联记录的条数,不要写一个特殊的查询。例如,如果你的用户模型上有帖子和评论,使用 withCount()。
同时,在 Blade 文件中,您可以通过使用 {relationship}_count 属性获得这些数量:
也可以按照这些统计字段进行排序:
关联关系中过滤查询
假如您想加载关联关系的数据,同时需要指定一些限制或者排序的闭包函数。例如,您想获取人口最多的前 3 座城市信息,可以按照如下方式实现:
动态预加载相关模型
您不仅可以实现对关联模型的实时预加载,还可以根据情况动态设置某些关联关系,需要在模型初始化方法中处理:
使用 hasMany 代替 belongsTo
在关联关系中,如果创建子关系的记录中需要用到父关系的 ID ,那么使用 hasMany 比使用 belongsTo 更简洁。
重命名 pivot 表名称
如果你想要重命名 pivot 并用其他的什么方式来调用关系,你可以在你的关系声明中使用 ->as('name') 来为关系取名。 模型 :
控制器:
仅用一行代码更新归属关系
如果有一个 belongsTo() 关系,你可以在仅仅一条语句中更新这个 Elquent 关系:
Laravel 7+ 的外键
从 Laravel 7 开始,你不需要在迁移(migration)中为一些关系字段写两行代码 —— 一行是字段,一行是外键。你可以使用 foreignId() 方法。
两种 「whereHas」 组合使用
在 Eloquent 中,你可以在同一条语句中使用 whereHas() 和 orDoesntHave()。
检查关系方法是否已经存在
如果你的 Eloquent 关系名是动态的,那么你需要检查项目中是否存在相同名称的关系。你可以使用这个 PHP 方法 method_exists($object, $methodName)。
获取中间表中的关联关系数据
在多对多关系中,您定义的中间表里面可能会包含扩展字段,甚至可能包含其它的关联关系。 下面生成一个中间表模型
然后,给 belongsToMany() 指定 ->using() 方法。下面就是见证奇迹的时刻:
便捷获取一对多关系中子集的数量
除了可以使用 Eloquent 中的 withCount() 方法统计子集数量外,还可以直接用 loadCount() 更加便捷和快速获取:
对关联模型数据进行随机排序
您可以使用 inRandomOrder() 对 Eloquent 的查询结果进行随机排序,同时也可以作用于关联关系中,实现关联数据的随机排序。
过滤一对多关联
通过我项目中的一个代码例子,展示了过滤一对多关系的可能性。TagType -> hasMany tags -> hasMany examples
如果你想查询所有的标签类型,伴随他们的标签,但只包含有实例的标签,并按照实例数量倒序
通过中间表字段过滤多对多关联
如果你有一个多对多关联,你可以在中间表中添加一个额外字段,这样你可以在查询列表时用它排序。
whereHas 的一个更简短的方法
在 Laravel 8.57 中发布:通过包含一个简单条件的简短方法来写 whereHas()。
你可以为你的模型关联添加条件
由 @anwar_nairi 提供
新的 Eloquent 查询构建器方法 whereBelongsTo()
Laravel 8.63.0 版本带有一个新的 Eloquent 查询构建器方法 whereBelongsTo() 。这允许你从你的查询中删除 BelongsTo 外键名称,并使用关联方法替代(该方法会根据类名自动确定关联与外键,也可以添加第二个参数手动关联)
由 @danjharrin 提供
使用is()方法比较一对一关系模型
我们可以在相关联的模型中做比较 而不需要其他数据库访问。
由 @PascalBaljet 提供
whereHas多连接
由 @adityaricki 提供
更新存在的中间记录
如果要更新表上存在中间记录,请使用 updateExistingPivot 而不是syncWithPivotValues。
由 @sky_0xs 提供
获取最新或最老数据的关系
Laravel 8.42 更新,一个模型中我们可以定义一个关系,该关系将获得另一个关系的最新(或最旧)项。
用 ofMany 代替你的自定义查询
由 @LaravelEloquent 提供
在关系上使用 orWhere 时避免数据泄漏
所有投票数大于或等于 100 的帖子都会被返回。
返回投票数大于或等于 100 的用户帖子。
由 @BonnickJosh 提供
最后更新于
这有帮助吗?