Laravel 的本地作用域和动态作用域的区别就是是否传递附加参数到作用域中。要定义一个作用域只需要在 scope
前加上一个 Eloquent 模型方法即可。
示例:在话题中,我们需要一个排序的逻辑:
Models/Topic.php
public function scopeWithOrder($query, $order)
{
// 不同的排序,使用不同的数据读取逻辑
switch ($order) {
case 'recent':
$query->recent();
break;
default:
$query->recentReplied();
break;
}
// 预加载,处理 N+1 问题
return $query->with('user', 'category');
}
public function scopeRecent($query)
{
// 按照创建时间排序
return $query->orderBy('created_at', 'desc');
}
public function scopeRecentReplied($query)
{
return $query->orderBy('updated_at', 'desc');
}
作用域总是返回 查询构建器。一旦定义了作用域,则可以在查询模型时调用作用域方法。在进行方法调用时不需要加上 scope
前缀。如以上代码中的 recent()
和 recentReplied()
。
调用示例:
$topics = Topic::withOrder($request->input('order'))
->paginate();
tips:
对于本地作用域虽然模型中定义的方法有一个参数 $query
,但是在调用时是不需要传参的,$query
是 \Illuminate\Database\Eloquent\Builder
实例,Laravel 会自动注入。
只有动态作用域的参数我们才需要传参。上例中的 scopeWithOrder($query,$order)
我们只需要传入 order
参数到作用域中,$query
会自动注入。