Laravel: 如何对请求使用多个验证规则

Laravel: How to use multiple validation rules with requests

我有两个模型 UserProfile 一切正常并完美地创造了记录。

为了验证,我创建了如下请求 类。

用户请求

<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Validator;
use function __;
use function preg_match;

class UserRequest extends FormRequest
{
    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     * @todo set role based permission for the method
     *
     */
    public function authorize()
    {
        return TRUE;
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        Validator::extend(
            'without_spaces',
            function ($attr, $value) {
                return preg_match('/^\S*$/u', $value);
            },
            __('validation.username_space')
        );

        switch ($this->method()) {

            case 'POST':

                return [
                    'username' => 'required|string|without_spaces|max:255|unique:users',
                    'email'    => 'required|string|email|max:255|unique:users,email',
                    'password' => 'required|string|min:8|confirmed',
                    'role'     => 'required',
                ];

            case 'PUT':
            case 'PATCH':

                return [
                    'username' => 'sometimes|required|string|without_spaces|max:255|unique:users,username,' . $this->user->id,
                    'email'    => 'required|string|email|max:255|unique:users,email,' . $this->user->id,
                    'password' => 'nullable|string|min:8|confirmed',
                    'role'     => 'required',
                ];

            case 'GET':
            case 'DELETE':
            default:
                return [];
                break;
        }

    }
}

个人资料请求

<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Rule;
use function __;
use function preg_match;

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

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        Validator::extend('unique_field', function ($attributes, $value, $parameters, $validator) {
            return;
        },
            __('validation.username_space')
        );

        switch ($this->method()) {

            case 'POST':
            case 'PUT':
            case 'PATCH':

                return [
                    'first_name' => 'max:20',
                    'last_name'  => 'max:20',
                    'mobile'     => 'regex:/(01)[0-9]{9}/|digits:8 ',
                    'city'       => 'max:30',
                    'facebook'   => 'url',
                    'twitter'    => 'url',
                    'youtube'    => 'url',
                    'instagram'  => 'url',
                ];

            case 'GET':
            case 'DELETE':
            default:
                return [];
                break;
        }
    }
}

用户控制器

public function store(UserRequest $request)
{
    // begin transaction
    DB::beginTransaction();

    try {
        // create user
        $user = User::create([
            'username' => $request->username,
            'email'    => $request->email,
            'password' => Hash::make($request->password),
            'role'     => $request->role,
        ]);

        // set profile data
        $profile = new Profile([
            'first_name' => $request->first_name,
            'last_name'  => $request->last_name,
            'mobile'     => $request->mobile,
            'city'       => $request->city,
            'facebook'   => $request->facebook,
            'twitter'    => $request->twitter,
            'youtube'    => $request->youtube,
            'instagram'  => $request->instagram,
        ]);

        // save profile data
        $user->profile()->save($profile);

        // commit transaction
        DB::commit();

        // if user created
        if ($user) {
            return redirect(route('admin.users.index'))->with('success', __('messages.admin.feedback.user_created'));
        } else {
            return redirect(route('admin.users.index'))->with('error', __('messages.admin.feedback.user_created'));
        }

    } catch (Throwable $exception) {
        // rollback if error
        DB::rollBack();

        throw $exception;
    }

}

public function update(UserRequest $request, User $user)
{

    try {

        $user->email = $request->email;
        $user->role  = $request->role;

        if ($request->has('password')) {
            $user->password = Hash::make($request->password);
        }

        $user->save();

        // set profile data
        $profile = [
            'first_name' => $request->first_name,
            'last_name'  => $request->last_name,
            'mobile'     => $request->mobile,
            'city'       => $request->city,
            'facebook'   => $request->facebook,
            'twitter'    => $request->twitter,
            'youtube'    => $request->youtube,
            'instagram'  => $request->instagram,
        ];

        // save profile data
        $user->profile()->update($profile);

        return redirect(route('admin.users.index'))->with('success', __('messages.admin.feedback.user_updated'));

    } catch (Throwable $exception) {
        throw $exception;
    }
}

Question:

I have one single form for user fields and profile fields. Now I am not sure how to use both request classes in method to validate fields.

在您的 UserRequest class 中,您可以将规则分配给数组,而不是直接从 switch 语句中 returning 规则。为了我们的目的,我们称之为 $rules。然后您应该能够合并您个人资料中的规则 return 合并后的规则如下:

$profileRequest = new ProfileRequest(); // you may need to switch this to app()->make(ProfileRequest::class) if you get an error instantiating this

return array_merge($rules, $profileRequest->rules());

我找到了解决方法。在 storeupdate 方法中键入 ProfileRequest class 并使用它来验证配置文件字段。

用户控制器

public function store(UserRequest $request, ProfileRequest $profileRequest)
{
    // begin transaction
    DB::beginTransaction();

    try {
        // create user
        $user = User::create([
            'username' => $request->username,
            'email'    => $request->email,
            'password' => Hash::make($request->password),
            'role'     => $request->role,
        ]);

        // set profile data
        $profile = new Profile([
            'first_name' => $profileRequest->first_name,
            'last_name'  => $profileRequest->last_name,
            'mobile'     => $profileRequest->mobile,
            'city'       => $profileRequest->city,
            'facebook'   => $profileRequest->facebook,
            'twitter'    => $profileRequest->twitter,
            'youtube'    => $profileRequest->youtube,
            'instagram'  => $profileRequest->instagram,
        ]);

        // save profile data
        $user->profile()->save($profile);

        // commit transaction
        DB::commit();

        // if user created
        if ($user) {
            return redirect(route('admin.users.index'))->with('success', __('messages.admin.feedback.user_created'));
        } else {
            return redirect(route('admin.users.index'))->with('error', __('messages.admin.feedback.user_created'));
        }

    } catch (Throwable $exception) {
        // rollback if error
        DB::rollBack();

        throw $exception;
    }

}

public function update(UserRequest $request, ProfileRequest $profileRequest, User $user)
{

    try {

        $user->email = $request->email;
        $user->role  = $request->role;

        if ($request->has('password')) {
            $user->password = Hash::make($request->password);
        }

        $user->save();

        // set profile data
        $profile = [
            'first_name' => $profileRequest->first_name,
            'last_name'  => $profileRequest->last_name,
            'mobile'     => $profileRequest->mobile,
            'city'       => $profileRequest->city,
            'facebook'   => $profileRequest->facebook,
            'twitter'    => $profileRequest->twitter,
            'youtube'    => $profileRequest->youtube,
            'instagram'  => $profileRequest->instagram,
        ];

        // save profile data
        $user->profile()->update($profile);

        return redirect(route('admin.users.index'))->with('success', __('messages.admin.feedback.user_updated'));

    } catch (Throwable $exception) {
        throw $exception;
    }
}