Laravel проверка запроса (не параметров) - PullRequest
0 голосов
/ 01 ноября 2018

У меня есть маршрут POST: /tasks/{task}/start, который утверждает задачу для пользователя. Но прежде чем требовать, мне нужно проверить, что задача еще не была запущена (возможно, кем-то другим).

Laravel обеспечивает отличную поддержку для проверки параметров запроса. Если есть какие-либо проблемы с параметрами, тогда laravel использует умную магию, чтобы сообщить об этих ошибках. Если запрос был сделан с Ajax, то неудачная проверка приведет к красиво отформатированному json с ошибкой. Если запрос был сделан из Интернета, он перенаправит вас обратно withErrors.

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

Прямо сейчас я мог бы сделать что-то вроде:

public function start(Request $request, Task $task) {
    if ($task->isStarted()) {
        if ($request->isAjax()) {
            abort(400, "The task was already started");
        } else {
            redirect()->back()->withErrors("The task was already started");
        } 
    }
    // Task is not started. Let's start it...
}

Но мне интересно, есть ли какая-то нативная поддержка для проверки запроса по состоянию модели и разрешения Laravel обрабатывать сообщение об ошибке.

EDIT

Я нашел другое решение, но оно кажется довольно неуклюжим:

Validator::make($request->all(), [])->after(function ($validator) use ($task) {
    if ($task->isStarted()) {
            $validator->errors()->add('task', 'The task was already started');
    }
})->validate();

1 Ответ

0 голосов
/ 01 ноября 2018

Использование Laravel Policies / Gates .

Конечный результат будет выглядеть так:

public function start(Request $request, Task $task) 
{
    $this->authorize('start', $task);

    // Task is not started. Let's start it...
}

Как ты этого достиг? Это достигается путем определения политики. Давайте создадим TaskPolicy.

Сгенерируйте его

Запуск в консоли:

php artisan make:policy TaskPolicy

Зарегистрируйся

приложение / Поставщики / AuthServiceProvider.php

protected $policies = [
    \App\Task::class => \App\TaskPolicy::class,
];

Настройте его

приложение / Политика / TaskPolicy.php

<?php

namespace App\Policies;

use App\User;
use App\Task;

class TaskPolicy
{
    /**
     * Determine if the given task can be started/claimed by the user.
     *
     * @param  \App\User  $user
     * @param  \App\Task  $task
     * @return bool
     */
    public function start(User $user, Task $task)
    {
        // do your checks here.. you have access to the authenticated user and task

        return !$task->isStarted();
    }
}

Применить это

Как уже упоминалось в начале:

public function start(Request $request, Task $task) 
{
    $this->authorize('start', $task);

    // Task is not started. Let's start it...
}

Проверьте документацию для получения дополнительной информации. Возможно, вы захотите использовать Гейтс, если вы делаете это только один раз.

Эта ошибка будет автоматически возвращена как json или html, если авторизация не удалась. Он вернет 403 ошибка.

EDIT

Конечно, вы можете по-разному обрабатывать авторизацию в вашем контроллере.

Вместо $this->authorize('start', $task) вы можете сделать:

if (\Auth::user()->cannot('start', $task) ) {

}

Более того, в вашем виде лезвия я предполагаю, что у вас есть что-то вроде этого

<form method="post" action="route-here">
    <button type="submit">Start Task</button>
</form>

что вы можете сделать, это обернуть это @can .. @ endcan:

@can('start', @task)
<form method="post" action="route-here">
    <button type="submit">Start Task</button>
</form>
@endcan

Таким образом, пользователь не увидит кнопку, если не сможет запустить задачу.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...