我正在验证Nova中标签的字段,并且每个字段都是唯一的。如果用户输入first name
,它将存储为first-name
。但是,带有first name
的第二个条目将通过验证,因为该值在数据库中不存在。但是,当需要存储它时,它也已更改为first-name
,因此它无法满足数据库中的UNIQUE
约束。
我看过Nova验证的源代码,它在获取验证规则之前会抓取所有字段的副本,因此我无法更改规则本身中要检查的数据。
如何验证一个值在变异后而不是变异前是唯一的?
答案 0 :(得分:0)
可以向/nova/routes/api.php
中的Nova路由添加自定义中间件。由于中间件是在请求到达Nova之前运行的,因此此时可以更改字段。
// Resource Management...
Route::get('/{resource}', 'ResourceIndexController@handle');
Route::get('/{resource}/count', 'ResourceCountController@show');
Route::delete('/{resource}/detach', 'ResourceDetachController@handle');
Route::put('/{resource}/restore', 'ResourceRestoreController@handle');
Route::delete('/{resource}/force', 'ResourceForceDeleteController@handle');
Route::get('/{resource}/{resourceId}', 'ResourceShowController@handle');
Route::post('/{resource}', 'ResourceStoreController@handle');
Route::put('/{resource}/{resourceId}', 'ResourceUpdateController@handle')->middleware('pre-mutate');
Route::delete('/{resource}', 'ResourceDestroyController@handle');
我在pre-mutate
中添加了名为Route::put('/{resource}/{resourceId}', 'ResourceUpdateController@handle')
的中间件。
新的中间件已添加到/app/Http/Kernel.php
:
/**
* The application's route middleware.
*
* These middleware may be assigned to groups or used individually.
*
* @var array
*/
protected $routeMiddleware = [
'auth' => \App\Http\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
'can' => \Illuminate\Auth\Middleware\Authorize::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'pre-mutate' => \App\Http\Middleware\PreMutate::class,
'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
];
然后将中间件添加到app/Http/Middleware/PreMutate.php
中:
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Support\Str;
use Symfony\Component\HttpFoundation\ParameterBag;
class PreMutate
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
*
* @return mixed
*/
public function handle($request, Closure $next)
{
// Make sure only the Articles resource is affected
if ($request->route()->parameters()['resource'] === 'articles') {
if ($request->request->has('tag_name')) {
$request->request->set('tag_name', Str::slug($request->request->get('tag_name')));
}
}
return $next($request);
}
}
可能有更好的方法将此请求转发到适当的模型以正确更改值,而不是直接在其他人不希望查找的中间件中应用规则,但这应该会让您入门。 / p>