Laravel 在浅层嵌套资源中请求验证
Laravel request validation in shallow nested resource
我有两个资源
组织
组织用户
考虑到我想在这两种资源中创建并且创建必须遵循特定要求,我使用了 Request rules() 和 attributes()。
例如,由于组织需要有一个唯一的名称,我使用
public function rules()
{
return [
'name' => [
'required', 'min:3', Rule::unique((new Organization)->getTable())->ignore($this->route()->organization->id ?? null)
],
(...)
];
}
而且效果很好。采用相同的流程来验证组织用户
class OrganizationUserRequest extends FormRequest
{
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'user_id' => [
'required', 'exists:'.(new User)->getTable().',id', Rule::unique((new OrganizationUser)->getTable())->ignore($this->route()->user->id ?? null)
],
(...)
];
}
/**
* Get the validation attributes that apply to the request.
*
* @return array
*/
public function attributes()
{
return [
'user_id' => 'user',
(...)
];
}
}
那么我尝试添加的任何用户都会给我一个
The user has already been taken.
无论使用哪个用户。
OrganizationUser 模型是
class OrganizationUser extends Model
{
protected $fillable = [
'user_id', (...)
];
/**
* Get the user
*
* @return \App\User
*/
public function user()
{
return $this->belongsTo(User::class);
}
(...)
}
另外,OrganizationUserController 是
/**
* Show the form for creating a new organization
*
* @return \Illuminate\View\View
*/
public function create($id, Organization $model1, User $model2)
{
return view('organizations.users.create', [
'id'=> $id,
'organizations' => $model1::where('id',$id)->get(['id', 'name']),
'portal_users' => $model2->all(),
]);
}
以及 create.blade.php
中的那个字段
<div class="form-group{{ $errors->has('user_id') ? ' has-danger' : '' }}">
<label class="form-control-label" for="input-user_id">{{ __('User') }}</label>
<select name="user_id" id="input-organization" class="form-control{{ $errors->has('user_id') ? ' is-invalid' : '' }}" placeholder="{{ __('User') }}" required>
@foreach ($portal_users as $portal_user)
<option value="{{ $portal_user->id }}" {{ $portal_user->id == old('user_id') ? 'selected' : '' }}>{{ $portal_user->name }}</option>
@endforeach
</select>
@include('alerts.feedback', ['field' => 'user_id'])
</div>
为了解决这个问题,我完成了后续步骤
- 创建提供商
php artisan make:provider UniqueOrgUserServiceProvider
- 在该提供商中
<?php
namespace App\Providers;
use App\OrganizationUser;
use Illuminate\Support\ServiceProvider;
class UniqueOrgUserServiceProvider extends ServiceProvider
{
/**
* Bootstrap services.
*
* @return void
*/
public function boot()
{
\Validator::extend('uniqueorguser',
function($attribute, $value, $parameters, $validator)
{
$value1 = (int)request()->get($parameters[0]);
if (is_numeric($value) && is_numeric($value1))
{
return (!(OrganizationUser::where($attribute, $value)
->where($parameters[0], $value1)
->count() > 0));
}
return false;
});
}
/**
* Register services.
*
* @return void
*/
public function register()
{
//
}
}
- 在
config/app.php
中注册提供商
'providers' => [
/*
* Application Service Providers...
*/
App\Providers\UniqueOrgUserServiceProvider::class,
],
- 将
OrganizationUserRequest
改为
class OrganizationUserRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return auth()->check();
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'name' => [
'required', 'min:3'
],
'is_admin' => [
'required','boolean'
],
'organization_id' => [
'required', 'exists:'.(new Organization)->getTable().',id'
],
'user_id' => [
'required', 'uniqueorguser:organization_id', 'exists:'.(new User)->getTable().',id',
]
];
}
/**
* Get the validation attributes that apply to the request.
*
* @return array
*/
public function attributes()
{
return [
'user_id' => 'user',
'organization_id' => 'organization'
];
}
public function messages()
{
return [
'user_id.uniqueorguser' => 'The user already exists in this organization!'
];
}
}
我有两个资源
组织
组织用户
考虑到我想在这两种资源中创建并且创建必须遵循特定要求,我使用了 Request rules() 和 attributes()。
例如,由于组织需要有一个唯一的名称,我使用
public function rules()
{
return [
'name' => [
'required', 'min:3', Rule::unique((new Organization)->getTable())->ignore($this->route()->organization->id ?? null)
],
(...)
];
}
而且效果很好。采用相同的流程来验证组织用户
class OrganizationUserRequest extends FormRequest
{
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'user_id' => [
'required', 'exists:'.(new User)->getTable().',id', Rule::unique((new OrganizationUser)->getTable())->ignore($this->route()->user->id ?? null)
],
(...)
];
}
/**
* Get the validation attributes that apply to the request.
*
* @return array
*/
public function attributes()
{
return [
'user_id' => 'user',
(...)
];
}
}
那么我尝试添加的任何用户都会给我一个
The user has already been taken.
无论使用哪个用户。
OrganizationUser 模型是
class OrganizationUser extends Model
{
protected $fillable = [
'user_id', (...)
];
/**
* Get the user
*
* @return \App\User
*/
public function user()
{
return $this->belongsTo(User::class);
}
(...)
}
另外,OrganizationUserController 是
/**
* Show the form for creating a new organization
*
* @return \Illuminate\View\View
*/
public function create($id, Organization $model1, User $model2)
{
return view('organizations.users.create', [
'id'=> $id,
'organizations' => $model1::where('id',$id)->get(['id', 'name']),
'portal_users' => $model2->all(),
]);
}
以及 create.blade.php
中的那个字段<div class="form-group{{ $errors->has('user_id') ? ' has-danger' : '' }}">
<label class="form-control-label" for="input-user_id">{{ __('User') }}</label>
<select name="user_id" id="input-organization" class="form-control{{ $errors->has('user_id') ? ' is-invalid' : '' }}" placeholder="{{ __('User') }}" required>
@foreach ($portal_users as $portal_user)
<option value="{{ $portal_user->id }}" {{ $portal_user->id == old('user_id') ? 'selected' : '' }}>{{ $portal_user->name }}</option>
@endforeach
</select>
@include('alerts.feedback', ['field' => 'user_id'])
</div>
为了解决这个问题,我完成了后续步骤
- 创建提供商
php artisan make:provider UniqueOrgUserServiceProvider
- 在该提供商中
<?php
namespace App\Providers;
use App\OrganizationUser;
use Illuminate\Support\ServiceProvider;
class UniqueOrgUserServiceProvider extends ServiceProvider
{
/**
* Bootstrap services.
*
* @return void
*/
public function boot()
{
\Validator::extend('uniqueorguser',
function($attribute, $value, $parameters, $validator)
{
$value1 = (int)request()->get($parameters[0]);
if (is_numeric($value) && is_numeric($value1))
{
return (!(OrganizationUser::where($attribute, $value)
->where($parameters[0], $value1)
->count() > 0));
}
return false;
});
}
/**
* Register services.
*
* @return void
*/
public function register()
{
//
}
}
- 在
config/app.php
中注册提供商
'providers' => [
/*
* Application Service Providers...
*/
App\Providers\UniqueOrgUserServiceProvider::class,
],
- 将
OrganizationUserRequest
改为
class OrganizationUserRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return auth()->check();
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'name' => [
'required', 'min:3'
],
'is_admin' => [
'required','boolean'
],
'organization_id' => [
'required', 'exists:'.(new Organization)->getTable().',id'
],
'user_id' => [
'required', 'uniqueorguser:organization_id', 'exists:'.(new User)->getTable().',id',
]
];
}
/**
* Get the validation attributes that apply to the request.
*
* @return array
*/
public function attributes()
{
return [
'user_id' => 'user',
'organization_id' => 'organization'
];
}
public function messages()
{
return [
'user_id.uniqueorguser' => 'The user already exists in this organization!'
];
}
}