如何将连接添加到laravel验证程序的自定义存在规则?

如何将连接添加到laravel验证程序的自定义存在规则?

问题描述:

laravel中的验证器可以定制存在的数据库规则,例如,如果您需要检查额外的列。从the manual一个例子:如何将连接添加到laravel验证程序的自定义存在规则?

use Illuminate\Validation\Rule; 

Validator::make($data, [ 
    'email' => [ 
     'required', 
     Rule::exists('staff')->where(function ($query) { 
      $query->where('account_id', 1); 
     }), 
    ], 
]); 

在封闭的query没有typehinted,所以我不是很积极,这是什么样的对象。我可以看到,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:从staff SELECT COUNT(*)作为骨料,其中email = -thevalue-和(teamactive = 1))

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

从评论我添加$query->toSQL()该功能。这确实显示出相当预期的结果,但它不与我得到的错误计算:

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

为VAR转储'$查询 - > toSql()'尝试你得到什么。 '$ query'是'Illuminate \ Database \ Query \ Builder'的一个实例,所以你应该没有问题进行连接。 – TheFallen

+0

自定义验证规则怎么样? [doc here](https://laravel.com/docs/5.5/validation#custom-validation-rules) – Maraboc

+0

@Maraboc是的,这将是后备,但我认为这将是最可读/最好的方式来做它。 – Nanne

看来,DatabaseRule做一些神奇的,不管你在封盖构成。最后,它似乎只看到提供where条款(见Exists::__toString)。这些连接已经被保存为闭包内部的回显,但是这个存在规则只是查看了哪里。这就是看起来未知列错误的原因。

我曾尝试using功能,这似乎更适合那么where我在那里第一次,但没有帮助,因为系统使得它成为一个字符串,它形成了一个验证串,只是多恩斯t似乎支持连接。

长话短说,我刚刚创建一个自定义的验证规则与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; 
}