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
的工作人员来说,电子邮件必须存在,但如果团队(所有工作人员都是团队的一部分,这是一个separte表)应该具有某种属性,例如, team.active = 1
?
整个员工/团队的事情当然是一个例子
所以最后我想知道:我如何为此规则添加联接,以便我们确保员工的团队中有一列活跃的'那是1。
我的第一个问题可能是: $query
的类型是什么?我会想象这样的事情会很棒,但是没有理由怀疑这个有效:
Rule::exists('staff')->where(function ($query) {
$query
->join('team', 'team.team_id', '=', 'staff.team_id')
->where('team.active', 1);
})
这似乎不起作用。奇怪的是,连接本身不会导致错误,但似乎被忽略了:
找不到列:
1054未知栏' team.active'在' where子句'
(SQL:选择count(*)作为staff
的聚合,其中team
。active
= 1))
我本来希望这可以工作(因为我赌博这个功能在这里可用的小变化),或者因为我调用一个不存在的函数而得到错误。但我得到的是一个构建但没有连接的查询。
从评论中我添加了$query->toSQL()
到该功能。这确实显示了一个相当期望的结果,但它没有计算出我得到的错误:
select * from `staff`
inner join `teams` on `teams`.`team_id` = `staff`.`team_id`
where `teams`.`active` = ?
答案 0 :(得分:4)
似乎DatabaseRule
对你在闭包中提供的任何东西都有一些魔力。最后,它似乎只看了提供的where
子句(参见Exists::__toString
)。连接已保存为闭包内显示的回显,但是存在规则只查看where。这就是出现未知列错误的原因。
我确实尝试了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;
}