如何为laravel验证器的自定义存在规则添加连接?

时间:2017-10-11 08:41:59

标签: laravel join laravel-5 laravel-validation illuminate-container

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本身只有一些关于wherewherenot等的功能,但我希望在混合中添加联接。

举例说,对于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的聚合,其中email = -thevalue-和(teamactive = 1))

我本来希望这可以工作(因为我赌博这个功能在这里可用的小变化),或者因为我调用一个不存在的函数而得到错误。但我得到的是一个构建但没有连接的查询。

从评论中我添加了$query->toSQL()到该功能。这确实显示了一个相当期望的结果,但它没有计算出我得到的错误:

select * from `staff`
inner join `teams` on `teams`.`team_id` = `staff`.`team_id`
where `teams`.`active` = ?

1 个答案:

答案 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;
}