#laravel #laravel-8 #laravel-request
#laravel #laravel-8 #laravel-запрос
Вопрос:
Я использую проверку запроса для проверки ввода пользователя.
Это UpdateUser
:
<?php
namespace AppHttpRequests;
use IlluminateFoundationHttpFormRequest;
use IlluminateSupportArr;
use IlluminateSupportFacadesGate;
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
I, исключая строку текущего пользователя из уникальности:
'user.email' => "required|string|email|max:255|unique:users,email,{$user_id}",
Поскольку я хотел бы объединить UpdateUser
и StoreUser
, что было бы наиболее эффективным и читаемым способом определить, обновляю я или сохраняю?
Это мой текущий подход:
<?php
namespace AppHttpRequests;
use IlluminateFoundationHttpFormRequest;
use IlluminateSupportArr;
use IlluminateSupportFacadesGate;
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 и предоставить isUpdating()
по умолчанию.
Комментарии:
Ответ №1:
Ваш метод update и store — это разные типы запросов, у вас есть PUT
PATCH
метод and в вашем экземпляре запроса, поэтому вы можете проверить тип запроса следующим образом :
switch ($request->method()) {
case 'PATCH':
// do anything in 'patch request';
break;
case 'PUT':
// do anything in 'put request';
break;
default:
// invalid request
break;
}
Ответ №2:
Некоторое время назад я узнал о новом подходе к проверке, используя отдельный класс validator, и мне это очень нравится. Позвольте мне показать вам
Создайте каталог Validators
и класс внутри UserValidator
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();
}
}
Затем авторизация может быть выполнена в контроллере
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 Appuser $user
*/
public function update(Request $request, User $user)
{
$this->authorize('update_user', $user);
$data = (new UserValidator())->validate(
$request->all(),
$user
);
$user->fill($data)->save();
}
}
Это было предложено и объяснено (ручкой twitter) @themsaid