如何将连接添加到 laravel 验证器的自定义存在规则?
How can I add a join to a custom exists rule for a laravel validator?
laravel 中的验证器可以自定义现有数据库规则,例如,如果您需要检查额外的列。来自 the manual 的示例:
use Illuminate\Validation\Rule;
Validator::make($data, [
'email' => [
'required',
Rule::exists('staff')->where(function ($query) {
$query->where('account_id', 1);
}),
],
]);
闭包中的 query
没有类型提示,所以我不太确定这是什么类型的对象。我可以看到 DatabaseRule
本身只有一些关于 where
、wherenot
等的功能,但我希望在混合中添加一个连接。
举个例子说,电子邮件必须存在于 account_id = 1
的员工,但是如果团队(所有员工都是团队的一部分,这是一个单独的 table)应该有一个某些 属性,例如team.active = 1
?
整个staff/team当然是个例子
所以最后我想知道:我怎样才能向这个规则添加一个连接,这样我们就可以确保员工的团队有一个列 'active' 是 1。
我的第一个问题可能是:那个 $query
的类型是什么? 我想像这样的东西会很棒,但没有理由怀疑这是有效的:
Rule::exists('staff')->where(function ($query) {
$query
->join('team', 'team.team_id', '=', 'staff.team_id')
->where('team.active', 1);
})
这似乎不起作用。奇怪的是join本身并没有报错,但是好像被忽略了:
Column not found:
1054 Unknown column 'team.active' in 'where clause'
(SQL: select count(*) as aggregate from staff
where email
= -thevalue- and (team
.active
= 1))
我原以为它会起作用(我打赌这个函数在这里可用,所以会有小的变化),或者因为我调用了一个不存在的函数而出错。但是我得到的是一个构建但没有连接的查询。
根据评论,我向该函数添加了 $query->toSQL()
。这确实显示了一个相当预期的结果,但它没有计算我得到的错误:
select * from `staff`
inner join `teams` on `teams`.`team_id` = `staff`.`team_id`
where `teams`.`active` = ?
似乎 DatabaseRule
对您在该闭包中提供的任何内容都产生了某种魔力。最后,它似乎只查看提供的 where
子句(参见 Exists::__toString
)。连接已保存为闭包内的回显显示,但存在规则仅查看位置。这就是未知列错误的原因。
我确实尝试了 using
函数,它似乎比我最初使用的 where
更适合,但这没有帮助,因为系统将它变成了一个字符串,形成一个似乎不支持连接的验证字符串。
长话短说,我刚刚使用 passes
函数创建了一个自定义验证规则,如下所示:
public function passes($attribute, $value)
{
$count = DB::table('staff')
->join('teams', 'teams.team_id', '=', 'staff.team_id')
->where([
['teams.active', '=', 1],
['staff.email', '=', $value]
])->count();
return $count > 0;
}
laravel 中的验证器可以自定义现有数据库规则,例如,如果您需要检查额外的列。来自 the manual 的示例:
use Illuminate\Validation\Rule;
Validator::make($data, [
'email' => [
'required',
Rule::exists('staff')->where(function ($query) {
$query->where('account_id', 1);
}),
],
]);
闭包中的 query
没有类型提示,所以我不太确定这是什么类型的对象。我可以看到 DatabaseRule
本身只有一些关于 where
、wherenot
等的功能,但我希望在混合中添加一个连接。
举个例子说,电子邮件必须存在于 account_id = 1
的员工,但是如果团队(所有员工都是团队的一部分,这是一个单独的 table)应该有一个某些 属性,例如team.active = 1
?
整个staff/team当然是个例子
所以最后我想知道:我怎样才能向这个规则添加一个连接,这样我们就可以确保员工的团队有一个列 'active' 是 1。
我的第一个问题可能是:那个 $query
的类型是什么? 我想像这样的东西会很棒,但没有理由怀疑这是有效的:
Rule::exists('staff')->where(function ($query) {
$query
->join('team', 'team.team_id', '=', 'staff.team_id')
->where('team.active', 1);
})
这似乎不起作用。奇怪的是join本身并没有报错,但是好像被忽略了:
Column not found:
1054 Unknown column 'team.active' in 'where clause'
(SQL: select count(*) as aggregate fromstaff
whereteam
.active
= 1))
我原以为它会起作用(我打赌这个函数在这里可用,所以会有小的变化),或者因为我调用了一个不存在的函数而出错。但是我得到的是一个构建但没有连接的查询。
根据评论,我向该函数添加了 $query->toSQL()
。这确实显示了一个相当预期的结果,但它没有计算我得到的错误:
select * from `staff`
inner join `teams` on `teams`.`team_id` = `staff`.`team_id`
where `teams`.`active` = ?
似乎 DatabaseRule
对您在该闭包中提供的任何内容都产生了某种魔力。最后,它似乎只查看提供的 where
子句(参见 Exists::__toString
)。连接已保存为闭包内的回显显示,但存在规则仅查看位置。这就是未知列错误的原因。
我确实尝试了 using
函数,它似乎比我最初使用的 where
更适合,但这没有帮助,因为系统将它变成了一个字符串,形成一个似乎不支持连接的验证字符串。
长话短说,我刚刚使用 passes
函数创建了一个自定义验证规则,如下所示:
public function passes($attribute, $value)
{
$count = DB::table('staff')
->join('teams', 'teams.team_id', '=', 'staff.team_id')
->where([
['teams.active', '=', 1],
['staff.email', '=', $value]
])->count();
return $count > 0;
}