Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Validation in controller

I am very new to Laravel, and I need some help with refactoring my code. Now, method is not covered in tests in 100% because I cannot mock validator object and its responses. I have following method in my cotroller

public function store(Request $request)
{
    $data = $request->only([
        'name',
        'email',
        'message',
    ]);

    $validator = Validator::make($data, $this->validatorRules);

    if ($validator->fails()) {
        return $this->response->errorFromValidator($validator);
    }

    $savedItem = $this->repository->store($data);

    if (!$savedItem) {
        return $this->response->error('Cannot save');
    }

    return $this->response->succesItem($savedItem);
}

I tried to inject validator in controller's constructor:

function __construct(Response $response, Repository $repository, Validator $validator)
{
    $this->response = $response;
    $this->repository = $repository;
    $this->validator= $validator;
}

and use it in method:

$this->validator::make($data, $this->validatorRules);

but I was getting syntax error, unexpected '::' (T_PAAMAYIM_NEKUDOTAYIM). How can I abstract validator outside the method, so I can mock validator in tests?

like image 944
user1292810 Avatar asked Dec 15 '25 08:12

user1292810


1 Answers

Why are you using Validator to validate your data ?

  • Using Request will keep your controller clean and Minimal. But some time it is sensible to use Validator within controller, e.g you know there is going to be just one field to validate, then it would be overkill to use FormRequest. So it is a matter of preferance.
  • Request classes are the better way to validate requests, because they help to extract this functionality from the constructor method, which should be as clean as possible.

Instead of using Validator inside your controller I suggest you to use Requests to validate your form data. From your code I can notice that your trying to save a contact form, so here my suggestion :

Run this command, this will create a ContactRequest file inside "Requests" folder :

php artisan make:request ContactRequest

ContactRequest file :

<?php

namespace App\Http\Requests;

use App\Http\Requests\Request;

class ContactRequest extends Request
{
    /**
     * 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|min:5|max:20|alpha',
            'email' => 'required|email',
            'message' => 'required|max:250'
        ];
    }
}

Note : You must set autorize to return true; to avoid not authorized error.

Your controller :

<?php namespace App\Http\Controllers;

use App\Http\Requests\ContactRequest;

class ContactController extends Controller {

function __construct(Repository $repository)
{
    $this->repository = $repository;
}

public function store(ContactRequest $request)
{
    return $this->repository->store($data);
}

}

In your view file you can handle errors like this :

    @if (count($errors) > 0)
        <div class="alert alert-danger">
        <button class="close" data-close="alert"></button>
                @foreach ($errors->all() as $error)
                    <span>{{ $error }}</span>
                @endforeach
        </div>
    @endif

Or if you prefer showing errors one by one you can do like this :

{!! $errors->first('name', '<small class="help-block">:message</small>') !!}
{!! $errors->first('email', '<small class="help-block">:message</small>') !!}
{!! $errors->first('message', '<small class="help-block">:message</small>') !!}

Your data get stored only if data is validated by ContactRequest.

Now your method should be covered in tests and you can notice how clean your controller become.

like image 85
Mohamed Salem Lamiri Avatar answered Dec 16 '25 22:12

Mohamed Salem Lamiri



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!