如何在Laravel中使用form-request时检查验证是否失败?

时间:2018-01-06 01:54:40

标签: php laravel laravel-5 laravel-5.4 laravel-5.5

我正在尝试为API编写CRUD。但是,当验证失败时,我不想将用户重定向到主页,而是希望返回基于json的错误响应。

我可以使用以下代码

来做到这一点
public function store(Request $request)
{
    try {
        $validator = $this->getValidator($request);

        if ($validator->fails()) {
            return $this->errorResponse($validator->errors()->all());
        }

        $asset = Asset::create($request->all());

        return $this->successResponse(
            'Asset was successfully added!',
            $this->transform($asset)
        );
    } catch (Exception $exception) {
        return $this->errorResponse('Unexpected error occurred while trying to process your request!');
    }
}

/**
 * Gets a new validator instance with the defined rules.
 *
 * @param Illuminate\Http\Request $request
 *
 * @return Illuminate\Support\Facades\Validator
 */
protected function getValidator(Request $request)
{
    $rules = [
        'name' => 'required|string|min:1|max:255',
        'category_id' => 'required',
        'cost' => 'required|numeric|min:-9999999.999|max:9999999.999',
        'purchased_at' => 'nullable|string|min:0|max:255',
        'notes' => 'nullable|string|min:0|max:1000',
    ];

    return Validator::make($request->all(), $rules);
}

现在,我想将我的一些代码提取到form-request中以清除我的控制器。我喜欢将我的代码更改为类似下面的代码。

public function store(AssetsFormRequest $request)
{
    try {
        if ($request->fails()) {
            return $this->errorResponse($request->errors()->all());
        }            
        $asset = Asset::create($request->all());

        return $this->successResponse(
            'Asset was successfully added!',
            $this->transform($asset)
        );
    } catch (Exception $exception) {
        return $this->errorResponse('Unexpected error occurred while trying to process your request!');
    }
}

您可能会说$request->fails()$request->errors()->all()不起作用。如何检查请求是否失败,以及如何从表单请求中获取错误?

供您参考,以下是我的AssetsFormRequest课程的样子

<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class AssetsFormRequest extends FormRequest
{
    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize()
    {
        return true;
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        return [
            'name' => 'required|string|min:1|max:255',
            'category_id' => 'required',
            'cost' => 'required|numeric|min:-9999999.999|max:9999999.999',
            'purchased_at' => 'nullable|string|min:0|max:255',
            'notes' => 'nullable|string|min:0|max:1000',
        ];
    }
}

3 个答案:

答案 0 :(得分:7)

在您的 AssetFormRequest 类中,您可以覆盖 failedValidation 方法,以便进行以下操作 -

public $validator = null;
protected function failedValidation(\Illuminate\Contracts\Validation\Validator $validator)
{
    $this->validator = $validator;
}

然后使用您的控制器方法,使用 $ validator 对象执行任何操作。可能类似于以下内容 -

if (isset($request->validator) && $request->validator->fails()) {
        return response()->json($request->validator->messages(), 400);
    }

您也可以看到this链接以获取更多详细信息。 希望它有所帮助:)

答案 1 :(得分:2)

将此功能添加到您的请求中:

const iosEdgePadding = { top: 100, right: 50, bottom: 300, left: 50 };

const androidEdgePadding = {
    top: PixelRatio.getPixelSizeForLayoutSize(iosEdgePadding.top),
    right: PixelRatio.getPixelSizeForLayoutSize(iosEdgePadding.right),
    bottom: PixelRatio.getPixelSizeForLayoutSize(iosEdgePadding.bottom),
    left: PixelRatio.getPixelSizeForLayoutSize(iosEdgePadding.left),
}

const edgePadding = (Platform.OS === 'android') ? androidEdgePadding : iosEdgePadding;

this.refs.map.fitToCoordinates([coordinate1, coordinate2], { edgePadding, animated: true })

答案 2 :(得分:0)

已经2年了,但这也许会对某人有所帮助。

您可以通过添加(在Laravel 6.0.4中进行测试)来覆盖AssetFormRequest中的getValidatorInstance()方法:

use Illuminate\Contracts\Container\BindingResolutionException;
use Illuminate\Contracts\Validation\Factory as ValidationFactory;
use Illuminate\Contracts\Validation\Validator;

/**
 * Get the validator instance for the request.
 *
 * @return Validator
 * @throws BindingResolutionException
 */
public function getValidatorInstance()
{
    if ($this->validator) {
        return $this->validator;
    }

    $factory = $this->container->make(ValidationFactory::class);

    if (method_exists($this, 'validator')) {
        $validator = $this->container->call([$this, 'validator'], compact('factory'));
    } else {
        $validator = $this->createDefaultValidator($factory);
    }

    if (method_exists($this, 'withValidator')) {
        $this->withValidator($validator);
    }

    $this->setValidator($validator);

    return $this->validator;
}

在那之后,验证者将在您的控制器中可用:

public function store(AssetsFormRequest $request)
{
    $validator = $request->getValidatorInstance();

    try {
        if ($validator->fails()) {
            return $this->errorResponse($validator->errors());
        }            
        $asset = Asset::create($validator->validated());

        return $this->successResponse(
            'Asset was successfully added!',
            $this->transform($asset)
        );
    } catch (Exception $exception) {
        return $this->errorResponse('Unexpected error occurred while trying to process your request!');
    }
}