我想为表单创建多个验证器,用于创建或编辑某些对象。
我有这种方法的User
模型:
public function rules()
{
return [
'name' => 'required|string|max:255',
'email' => 'required|string|email|max:255|unique:users',
'password' => 'required|string|min:6|confirmed',
];
}
我有默认资源UserController
:
public function store(Request $request, User $user)
{
request()->validate($user->rules()); //this is nice according to mvc pattern (I hope it is)
User::create([
...
]);
}
public function update(Request $request, $id)
{
request()->validate([
'name' => 'required|string|max:255',
'email' => 'required|string|email|max:255|unique:users',
'password' => 'required|string|min:6|confirmed',
]);
User::find($id)->update($request->all());
...
}
与update()
不同, User
方法没有store()
实例作为参数。但我不想要任何过多的代码。我应该rules()
静态并使用User::rules()
吗?我知道测试静态方法非常困难,但实际上我并不知道这种方式的优缺点。有什么好的解决方案吗?
答案 0 :(得分:0)
如果您使用相同的验证进行插入和更新,则更新时会出现问题,因为规则包含:
enter code here`'email' => 'required|string|email|max:255|unique:users'
这意味着更新将始终在'unique:users'验证失败,因为电子邮件已记录在数据库中。
我认为如果您愿意,静态功能也不错。编程风格很多,您可以选择自己的风格。决赛是相同的,让它发挥作用。
根据你的条件,我更喜欢把它变成静态变量,而不是需要调用一个函数,因为规则只是一个字符串数组。但是你需要使用PHP7。
class User {
static $RULES = [
'name' => 'required|string|max:255',
'email' => 'required|string|email|max:255|unique:users',
'password' => 'required|string|min:6|confirmed',
];
}
然后当需要更新规则时,我将进行自定义唯一验证,除了参数之外可以接受,例如:
$rules = User::$RULES; //Clone
$rules[email] .= " id!={$user->id}" // Append with space
// Email rule will like this
// required|string|email|max:255|unique:users id!=23
然后我需要修改唯一验证以支持该参数。这个例子来处理它:
function unique($str_to_validate, $rule)
{
if( strpos($rule, ' ') !== false )
{
//Has except object notation
list($rule, $condition) = explode(' ', $rule, 2);
//Add where condition on DB query
$this->db->where($condition);
}
// Your default validation here
// ...
}
答案 1 :(得分:0)
我建议使用FormRequests来保持代码分离。
https://laravel.com/docs/5.5/validation#form-request-validation
它们允许您在控制器方法中验证您的请求,而不是在验证数据到达验证器之前增加验证数据。
另一个很大的好处是authorize()
方法,您可以进一步微调谁可以访问路由方法以及如何访问。
您可以使用一组可以继承的通用规则定义BaseFormRequest类。
如果验证失败,它会自动将错误刷新到会话,或者如果请求是ajax,则返回JSON响应。