记录一些相对比较常用的特殊用例。
1、whereHas
有时在模型关联中会碰到需要跨模型判断条件来获取数据的情况,比如存在两张表 users 和 roles ,需要获取角色为 viki 的用户。
在模型关联时,官方已经提供了方法 whereHas,实际上最好还是去查看一下 laravel源码 会更容易理解,助手函数示例如下:
public static function whereHas($relation, $callback = null, $operator = '>=', $count = 1)
{
return $instance->whereHas($relation, $callback, $operator, $count);
}
此处该查询语句可以这样写:
User::whereHas('role', function($query) {
$query->where('name', 'viki');
})->get();
当然,肯定也是存在 orWhereHas 该方法的。
2、when
在做查询语句时,经常会碰到需要判断上一个条件是否为真则执行语句的问题。这种情况下很容易拆成两段 sql 语句查询,实际上用 when 即可解决,给出 _ide_helper 的代码追踪:
public static function when($value, $callback, $default = null)
{
return $instance->when($value, $callback, $default);
}
实际上的使用参考如下:
public function gainTodoList($userIds, $supervisorUserIDs)
{
return $this->todoSummaryRepository
->orderByDesc('created_at')
->where('status', 1)
->where('type', 1)
->when(Admin::user()->isAdministrator(), function ($query) use ($supervisorUserIDs) {
$supervisorUserIDs = array_merge([Admin::user()->id], $supervisorUserIDs);
$query->whereIn('executor_id', $supervisorUserIDs);
})
->when(!Admin::user()->isAdministrator(), function ($query) use ($userIds) {
$query->when($userIds, function ($query) use ($userIds) {
$userIds = array_merge([Admin::user()->id], $userIds);
$query->whereIn('executor_id', $userIds);
})
->when(!$userIds, function ($query) {
$query->where('executor_id', Admin::user()->id);
});
})
->get();
}
不难看出,when 会判断第一个参数的真与假,如果是真,则执行第一个 callback,如果是假,则执行默认的方法,代码就只设置了真的时候需要执行的代码,因为条件有三种,不只有两种。这样的话可以使代码易读性更好,当然也可以拆分子句,但是 when 这个用法相对更赞。
很显然,该方法中的最后一个 when 的超管不存在的条件判断,只要放入到上一个 when 方法的最后一个闭包函数内即可:
public function gainTodoList($userIds, $supervisorUserIDs)
{
return $this->todoSummaryRepository
->orderByDesc('created_at')
->where('status', 1)
->where('type', 1)
->when(
Admin::user()->isAdministrator(),
function ($query) use ($supervisorUserIDs) {
$supervisorUserIDs = array_merge([Admin::user()->id], $supervisorUserIDs);
$query->whereIn('executor_id', $supervisorUserIDs);
},
function ($query) use ($userIds) {
$query->when($userIds, function ($query) use ($userIds) {
$userIds = array_merge([Admin::user()->id], $userIds);
$query->whereIn('executor_id', $userIds);
})
->when(!$userIds, function ($query) {
$query->where('executor_id', Admin::user()->id);
});
})
->get();
}
todo 后续如有则继续补充
laravel 6
版本关于查询构造的方法文件位于该路径:
vendor/laravel/framework/src/Illuminate/Database/Eloquent
vendor/laravel/framework/src/Illuminate/Database/Query
// 模型关联的方法文件
vendor/laravel/framework/src/Illuminate/Database/Query/Builder.php