2

I have two models User and Profile everything is working fine and creating a record perfectly.

For validation, I have created request classes as below.

UserRequest

<?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;
        }

    }
}

ProfileRequest

<?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;
        }
    }
}

UserController

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.

2 Answers 2

4

I have found a workaround. Type-hit the ProfileRequest class in store and update methods and used it to validate profile fields.

UserController

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;
    }
}
Sign up to request clarification or add additional context in comments.

Comments

0

In your UserRequest class instead of returning the rules directly from the switch statement you can assign them to an array. Let call it $rules for our purposes. Then you should be able to merge in the rules from your profile return the merged rules like so:

$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());

4 Comments

Getting error ErrorException array_merge(): Expected parameter 2 to be an array, object given
If I pass $profileRequest->rules() then getting the following error Class 'App\Http\Requests\Validator' not found
That's because you are missing use Illuminate/Validation/Validator; in ProfileRequest, try fixing that and see what happens
Yes, I realized that. But even then after also not working. It is not considering the rule for the ProfileRequest. So finally I found a workaround. I have type-hint the ProfileRequest to the method and use it to validate profile fields and everything is working fine. Thanks for your help. I appreciate.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.