如何创建嵌套模型的验证以在 Laravel 中调用请求
How create validation of nested model to call in request in Laravel
我有一个数据库 table 结构如下(在 laravel 中):
- 用户 1-1 个人资料
- 合作伙伴 1-1 资料
- 用户1-N部门
我想发送保存请求 (post) 并让用户在 UserRequest 中验证并让此 class 调用 ProfileRequest。
- 这可以吗?
- 有什么方法可以对相关模型进行验证吗?
Class 的用户请求示例:
class UserRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'name' => 'required|string',
'lastname' => 'required|string',
'user' => [
'required',
Rule::unique('users')->ignore($this),
],
'email' => 'required|string|email|unique:users',
'password' => 'required|string|confirmed',
'headquarter_id' => 'required'
//Validation of profile
];
}
}
控制器用户示例
public function store(AdAszaUserRequest $request)
{
$input = $request->all();
$validated = $request->validated();
$input['password'] = \Hash::make($request['password']);
//
$departmentidList = array_column($input['departments'], 'id');
$AszaUser = AdAszaUser::create($input);
$models = [];
foreach ($input['departments'] as $model) {
$models[] = new AdDepartment($model);
}
///important: this line add departments without validation
$AszaUser->departments()->saveMany($models);
$AszaUser->departments()->sync($departmentidList);
return response($AszaUser, 201);
}
部门要求:
<?php
namespace App\Http\Requests\AD;
use Illuminate\Foundation\Http\FormRequest;
class AdDepartmentRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'name' => 'required|string|unique:ad_departments',
'internal_name' => 'required|string|unique:ad_departments'
];
}
}
Json 的示例发送 post:
{
"id":2,
"name": "Admin2",
"email": "test@gmail.com",
"lastname": "test",
"user": "test",
"password": "test",
"password_confirmation": "test",
"headquarter_id": 1,
"lastname":"test",
"remember_token": "1",
"email_verified_at": "test",
"headquarter": {
"id": 1,
"name": "ASZA ZARAGOZA",
"description": "Sede en Zaragoza",
},
"departments": [
{
"id": 1,
"name": "Intérpretes",
"internal_name": "Interprete",
"description": "Departamento de Intérpretes",
"display_id": "01",
"pivot": {
"user_id": 1,
"department_id": 1
}
},
{
"id": 10,
"name": "Psicología"
}
]
}
我可以调用 DepartmentRequest 来验证部门数组中传递的元素吗?
是的,你可以这样做
public function rules() {
return [
'name' => 'required|string',
'lastname' => 'required|string',
'user' => [ 'required', Rule::unique('users')->ignore($this), ],
'email' => 'required|string|email|unique:users',
'password' => 'required|string|confirmed',
'headquarter_id' => 'required',
//Validation of profile
'profile.some_field' => 'required',
//For array of objects
'profile.*.some_field' => 'required',
];
}
更新:1
我觉得没必要,但当然可以
public function store(AdAszaUserRequest $request)
{
$input = $request->all();
$validated = $request->validated();
$input['password'] = \Hash::make($request['password']);
//
$departmentidList = array_column($input['departments'], 'id');
$AszaUser = AdAszaUser::create($input);
$models = [];
foreach ($input['departments'] as $model) {
/** To check validation for single item */
$validator = Validator::make($model, (new StoreEventRequest)->rules());
if (!$validator->fails()) {
$models[] = new AdDepartment($model);
} else {
/** Something wrong */
/** $errors = $validator->errors(); */
}
}
/** To check validation for array of data
$validator = Validator::make($request->only(['departments']), collect(array_map(function ($rules, $field): array {
return ['departments.*.' . $field => $rules];
}, (new StoreEventRequest)->rules()))
->collapse()
->toArray()); */
/**
* And then do what you want to do with this object
* $errors = $validator->errors();
*
if ($validator->fails()) {
return redirect('some_url')
->withErrors($validator);
} */
$AszaUser->departments()->saveMany($models);
$AszaUser->departments()->sync($departmentidList);
return response($AszaUser, 201);
}
有关详细信息,请参阅文档 https://laravel.com/docs/6.x/validation#manually-creating-validators
更新:2
如果你需要分离你的请求类,你也可以这样做
Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return array_merge([
'name' => 'required|string',
'lastname' => 'required|string',
'user' => [
'required',
Rule::unique('users')->ignore($this),
],
'email' => 'required|string|email|unique:users',
'password' => 'required|string|confirmed',
'headquarter_id' => 'required'
//Validation of profile
/** Validate of departments */
'departments' => 'nullable|array',
], collect(array_map(function ($rules, $field): array {
return ['departments.*.' . $field => $rules];
}, (new StoreEventRequest)->rules()))
->collapse()
->toArray())
->toArray();
}
}
我有一个数据库 table 结构如下(在 laravel 中):
- 用户 1-1 个人资料
- 合作伙伴 1-1 资料
- 用户1-N部门
我想发送保存请求 (post) 并让用户在 UserRequest 中验证并让此 class 调用 ProfileRequest。
- 这可以吗?
- 有什么方法可以对相关模型进行验证吗?
Class 的用户请求示例:
class UserRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'name' => 'required|string',
'lastname' => 'required|string',
'user' => [
'required',
Rule::unique('users')->ignore($this),
],
'email' => 'required|string|email|unique:users',
'password' => 'required|string|confirmed',
'headquarter_id' => 'required'
//Validation of profile
];
}
}
控制器用户示例
public function store(AdAszaUserRequest $request)
{
$input = $request->all();
$validated = $request->validated();
$input['password'] = \Hash::make($request['password']);
//
$departmentidList = array_column($input['departments'], 'id');
$AszaUser = AdAszaUser::create($input);
$models = [];
foreach ($input['departments'] as $model) {
$models[] = new AdDepartment($model);
}
///important: this line add departments without validation
$AszaUser->departments()->saveMany($models);
$AszaUser->departments()->sync($departmentidList);
return response($AszaUser, 201);
}
部门要求:
<?php
namespace App\Http\Requests\AD;
use Illuminate\Foundation\Http\FormRequest;
class AdDepartmentRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'name' => 'required|string|unique:ad_departments',
'internal_name' => 'required|string|unique:ad_departments'
];
}
}
Json 的示例发送 post:
{
"id":2,
"name": "Admin2",
"email": "test@gmail.com",
"lastname": "test",
"user": "test",
"password": "test",
"password_confirmation": "test",
"headquarter_id": 1,
"lastname":"test",
"remember_token": "1",
"email_verified_at": "test",
"headquarter": {
"id": 1,
"name": "ASZA ZARAGOZA",
"description": "Sede en Zaragoza",
},
"departments": [
{
"id": 1,
"name": "Intérpretes",
"internal_name": "Interprete",
"description": "Departamento de Intérpretes",
"display_id": "01",
"pivot": {
"user_id": 1,
"department_id": 1
}
},
{
"id": 10,
"name": "Psicología"
}
]
}
我可以调用 DepartmentRequest 来验证部门数组中传递的元素吗?
是的,你可以这样做
public function rules() {
return [
'name' => 'required|string',
'lastname' => 'required|string',
'user' => [ 'required', Rule::unique('users')->ignore($this), ],
'email' => 'required|string|email|unique:users',
'password' => 'required|string|confirmed',
'headquarter_id' => 'required',
//Validation of profile
'profile.some_field' => 'required',
//For array of objects
'profile.*.some_field' => 'required',
];
}
更新:1 我觉得没必要,但当然可以
public function store(AdAszaUserRequest $request)
{
$input = $request->all();
$validated = $request->validated();
$input['password'] = \Hash::make($request['password']);
//
$departmentidList = array_column($input['departments'], 'id');
$AszaUser = AdAszaUser::create($input);
$models = [];
foreach ($input['departments'] as $model) {
/** To check validation for single item */
$validator = Validator::make($model, (new StoreEventRequest)->rules());
if (!$validator->fails()) {
$models[] = new AdDepartment($model);
} else {
/** Something wrong */
/** $errors = $validator->errors(); */
}
}
/** To check validation for array of data
$validator = Validator::make($request->only(['departments']), collect(array_map(function ($rules, $field): array {
return ['departments.*.' . $field => $rules];
}, (new StoreEventRequest)->rules()))
->collapse()
->toArray()); */
/**
* And then do what you want to do with this object
* $errors = $validator->errors();
*
if ($validator->fails()) {
return redirect('some_url')
->withErrors($validator);
} */
$AszaUser->departments()->saveMany($models);
$AszaUser->departments()->sync($departmentidList);
return response($AszaUser, 201);
}
有关详细信息,请参阅文档 https://laravel.com/docs/6.x/validation#manually-creating-validators
更新:2 如果你需要分离你的请求类,你也可以这样做
Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return array_merge([
'name' => 'required|string',
'lastname' => 'required|string',
'user' => [
'required',
Rule::unique('users')->ignore($this),
],
'email' => 'required|string|email|unique:users',
'password' => 'required|string|confirmed',
'headquarter_id' => 'required'
//Validation of profile
/** Validate of departments */
'departments' => 'nullable|array',
], collect(array_map(function ($rules, $field): array {
return ['departments.*.' . $field => $rules];
}, (new StoreEventRequest)->rules()))
->collapse()
->toArray())
->toArray();
}
}