Проверьте мутировавшее значение в Nova - PullRequest
0 голосов
/ 29 января 2019

Я проверяю поле для тегов в Nova, и каждое из них должно быть уникальным.Если пользователь введет first name, оно будет сохранено как first-name.Однако вторая запись с first name пройдет проверку, потому что это значение не существует в базе данных.Но когда пришло время сохранить его, он также был изменен на first-name, поэтому он не выдерживает ограничение UNIQUE в базе данных.

Я посмотрел исходный код для проверки Nova, и онзахватывает копию всех полей до того, как получит правила проверки, поэтому я не могу изменить данные, проверяемые в самих правилах.

Как проверить, что значение является уникальным после того, как оно было изменено, а не передбыть мутировавшим?

1 Ответ

0 голосов
/ 01 февраля 2019

Можно добавить пользовательское промежуточное ПО для маршрутов Nova в /nova/routes/api.php.Поскольку промежуточное программное обеспечение запускается до того, как запрос поступает в 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);
    }
}

Возможно, существует более удобный способ переслать этот запрос соответствующемуМодель для правильного изменения значения, а не для применения правила непосредственно в промежуточном программном обеспечении, когда другие не будут думать, что нужно его искать, но это должно помочь вам начать работу.

...