Laravel验证请求(不是参数)

时间:2018-11-01 03:55:16

标签: laravel

我有一条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处理错误的传达。

编辑

我找到了另一种解决方案,但看起来很笨拙:

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

1 个答案:

答案 0 :(得分:0)

使用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

注册

app / Providers / AuthServiceProvider.php

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

自定义它

app / Policies / 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...
}

查看documentation了解更多信息。如果只执行一次,则可能要使用盖茨。

如果授权失败,此错误将自动以jsonhtml的形式返回。它将返回403错误。

编辑

您当然可以在控制器中以不同方式处理授权。

您可以代替$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

这样,如果用户无法启动任务,用户将不会看到该按钮。