合并表单请求验证以进行存储和更新
Merge Form Request Validation for store and update
我正在使用请求验证来验证用户的输入。
这是UpdateUser
:
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Gate;
class UpdateUser extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return Gate::allows('update-user');
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
$user_id = Arr::get($this->request->get('user'), 'id');
return [
'user.firstname' => 'required|string|max:255',
'user.lastname' => 'required|string|max:255',
'user.email' => "required|string|email|max:255|unique:users,email,{$user_id}",
'user.password' => 'sometimes|nullable|string|min:4|confirmed',
];
}
}
如您所见,发生了一些 update
特定的事情:
authorize()
方法检查用户是否被允许 update-user
并且在 rules
中我排除了当前用户的行是唯一的:
'user.email' => "required|string|email|max:255|unique:users,email,{$user_id}",
因为我想合并 UpdateUser
和 StoreUser
,确定我是更新还是保存的最有效和可读的方法是什么?
这是我目前的做法:
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Gate;
class UpdateUser extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
if($this->isUpdating())
{
return Gate::allows('update-user');
}
return Gate::allows('create-user');
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
if($this->isUpdating()){
$user_id = Arr::get($this->request->get('user'), 'id');
return [
...
];
}
return [];
}
/**
* @return bool
*/
protected function isUpdating(){
return $this->isMethod('put') || $this->isMethod('patch');
}
}
我想知道我是否可以扩展 FormRequest class 并默认提供 isUpdating()
。
您的更新和存储方法不是同一请求类型,您的请求实例上有 PUT
和 PATCH
方法,因此您可以像这样检查请求类型:
switch ($request->method()) {
case 'PATCH':
// do anything in 'patch request';
break;
case 'PUT':
// do anything in 'put request';
break;
default:
// invalid request
break;
}
前段时间我了解了一种使用单独验证器 class 进行验证的新方法,我非常喜欢它。让我告诉你
在UserValidator
中创建一个目录Validators
和一个class
class UserValidator
{
public function rules(User $user)
{
return [
'user.firstname' => [
'required',
'string',
'max:255',
],
'user.lastname' => [
'required',
'string',
'max:255',
],
'user.email' => [
$user->exists ? 'sometimes' : null,
'required',
'string',
'email',
'max:255',
Rule::unique('users', 'email')->ignore($user->exists ? $user->id : null)
],
'user.password' => [
$user->exists ? 'sometimes' : null,
'required',
'string',
'min:8'
],
];
}
public function validate(array $data, User $user)
{
return validator($data, $this->rules($user))
//->after(function ($validator) use ($data, $user) {
// Custom validation here if need be
//})
->validate();
}
}
然后可以在Controller中进行授权
class UserController
{
use AuthorizesRequests;
/**
* @param Request $request
*/
public function store(Request $request)
{
$this->authorize('create_user', User::class);
$data = (new UserValidator())->validate(
$request->all(),
$user = new User()
);
$user->fill($data)->save();
}
/**
* @param Request $request
* @param \App\user $user
*/
public function update(Request $request, User $user)
{
$this->authorize('update_user', $user);
$data = (new UserValidator())->validate(
$request->all(),
$user
);
$user->fill($data)->save();
}
}
这是由(推特用户名)@themsaid 提出并解释的
我正在使用请求验证来验证用户的输入。
这是UpdateUser
:
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Gate;
class UpdateUser extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return Gate::allows('update-user');
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
$user_id = Arr::get($this->request->get('user'), 'id');
return [
'user.firstname' => 'required|string|max:255',
'user.lastname' => 'required|string|max:255',
'user.email' => "required|string|email|max:255|unique:users,email,{$user_id}",
'user.password' => 'sometimes|nullable|string|min:4|confirmed',
];
}
}
如您所见,发生了一些 update
特定的事情:
authorize()
方法检查用户是否被允许 update-user
并且在 rules
中我排除了当前用户的行是唯一的:
'user.email' => "required|string|email|max:255|unique:users,email,{$user_id}",
因为我想合并 UpdateUser
和 StoreUser
,确定我是更新还是保存的最有效和可读的方法是什么?
这是我目前的做法:
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Gate;
class UpdateUser extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
if($this->isUpdating())
{
return Gate::allows('update-user');
}
return Gate::allows('create-user');
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
if($this->isUpdating()){
$user_id = Arr::get($this->request->get('user'), 'id');
return [
...
];
}
return [];
}
/**
* @return bool
*/
protected function isUpdating(){
return $this->isMethod('put') || $this->isMethod('patch');
}
}
我想知道我是否可以扩展 FormRequest class 并默认提供 isUpdating()
。
您的更新和存储方法不是同一请求类型,您的请求实例上有 PUT
和 PATCH
方法,因此您可以像这样检查请求类型:
switch ($request->method()) {
case 'PATCH':
// do anything in 'patch request';
break;
case 'PUT':
// do anything in 'put request';
break;
default:
// invalid request
break;
}
前段时间我了解了一种使用单独验证器 class 进行验证的新方法,我非常喜欢它。让我告诉你
在UserValidator
Validators
和一个class
class UserValidator
{
public function rules(User $user)
{
return [
'user.firstname' => [
'required',
'string',
'max:255',
],
'user.lastname' => [
'required',
'string',
'max:255',
],
'user.email' => [
$user->exists ? 'sometimes' : null,
'required',
'string',
'email',
'max:255',
Rule::unique('users', 'email')->ignore($user->exists ? $user->id : null)
],
'user.password' => [
$user->exists ? 'sometimes' : null,
'required',
'string',
'min:8'
],
];
}
public function validate(array $data, User $user)
{
return validator($data, $this->rules($user))
//->after(function ($validator) use ($data, $user) {
// Custom validation here if need be
//})
->validate();
}
}
然后可以在Controller中进行授权
class UserController
{
use AuthorizesRequests;
/**
* @param Request $request
*/
public function store(Request $request)
{
$this->authorize('create_user', User::class);
$data = (new UserValidator())->validate(
$request->all(),
$user = new User()
);
$user->fill($data)->save();
}
/**
* @param Request $request
* @param \App\user $user
*/
public function update(Request $request, User $user)
{
$this->authorize('update_user', $user);
$data = (new UserValidator())->validate(
$request->all(),
$user
);
$user->fill($data)->save();
}
}
这是由(推特用户名)@themsaid 提出并解释的