TrOnNe
TrOnNe

Reputation: 1772

Laravel rules with condition and custom error messages

I want to optimize the code to make it more efficient and scalable.

So I want to merge this part into one:

if($request->input('logintype') == 'register'){
    $validator = Validator::make($request->all(), [
        'option.*' => 'required|integer',
        'quantity.*' => 'required|integer',
        'conditions' => 'required',
        'comission' => 'required',
    ],[
        'option.integer' => 'Debe introducir una opción válida',
        'quantity.required' => 'Introduzca una cantidad a comprar',
        'quantity.integer'  => 'Debe introducir una cantidad válida',
        'quantity.*.max'  => 'Se ha superado el límite máximo de tickets por persona',
        'conditions.required'  => 'Debe aceptar los Términos y Condiciones',
        'comission.required'  => 'Debe seleccionar el método de pago',
    ]);

}
else{
    $validator = Validator::make($request->all(), [
        'option.*' => 'integer',
        'quantity.*' => 'required|integer',
        'comission' => 'required',
    ],[
        'option.integer' => 'Debe introducir una opción válida',
        'quantity.required' => 'Introduzca una cantidad a comprar',
        'quantity.integer'  => 'Debe introducir una cantidad válida',
        'quantity.*.max'  => 'Se ha superado el límite máximo de tickets por persona',
        'comission.required'  => 'Debe seleccionar el método de pago',

    ]);

}

I've check that this is possible with this code:

$validator->sometimes('conditions', 'required', function($request){
   return $request->input('logintype') == 'register';
});

But I'm unsure how to deal with the custom error messages.

Upvotes: 2

Views: 4498

Answers (3)

alistaircol
alistaircol

Reputation: 1453

As Kyslik said, adding this logic to a Request would make things a little neater in your controller.

I tend to go with the following style of a Request containing the validation rules and custom validation messages. In your case it could look something like this:

<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;
use Validator;

class LoginRequest 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()
  {
    if ($this->input('logintype') == 'register') {
      return [
        'option.*' => 'required|integer',
        'quantity.*' => 'required|integer',
        'conditions' => 'required',
        'comission' => 'required',
      ];
    }

    return [
      'option.*' => 'integer',
      'quantity.*' => 'required|integer',
      'comission' => 'required',
    ];
  }

  public function messages()
  {
    if ($this->input('logintype') == 'register') {
      return [
        'option.integer' => 'Debe introducir una opción válida',
        'quantity.required' => 'Introduzca una cantidad a comprar',
        'quantity.integer'  => 'Debe introducir una cantidad válida',
        'quantity.*.max'  => 'Se ha superado el límite máximo de tickets por persona',
        'conditions.required'  => 'Debe aceptar los Términos y Condiciones',
        'comission.required'  => 'Debe seleccionar el método de pago',
      ];
    }

    return [
      'option.integer' => 'Debe introducir una opción válida',
      'quantity.required' => 'Introduzca una cantidad a comprar',
      'quantity.integer'  => 'Debe introducir una cantidad válida',
      'quantity.*.max'  => 'Se ha superado el límite máximo de tickets por persona',
      'comission.required'  => 'Debe seleccionar el método de pago',
    ];
  }

  public function validate()
  {
    return Validator::make(parent::all(), $this->rules(), $this->messages());
  }
}

And in the controller use like this:

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Http\Response;
use App\Requests\LoginRequest;

class LoginController extends Controller
{
  public function search(LoginRequest $request)
  {
    $status_code = 200;
    $response = [];

    try {
      $validator = $request->validate();
      if ($validator->fails()) {
        // throw new ValidationException or something similar
      }

    } catch (Exception $e) {
      // Deal with it
    } finally {
      return response()->json($response, $status_code);
    }
  }
}

As you can see it makes the controller tidier.

In your LoginRequest you can customise it heavily, change rules depending on some of the inputs or the HTTP method used, e.g. different between POST and GET, etc.

Hope this helps.

Upvotes: 1

iamab.in
iamab.in

Reputation: 2070

You may use required_if to conditionally add the required rule. In this scenario required_if rule is added to the fields option and conditions.

FormRequest is used for separating validation logic from controller.

<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class YourRequestClassName extends FormRequest
{
    public function authorize()
    {
        return true;
    }

    public function messages()
    {
        return [
                'option.integer' => 'Debe introducir una opción válida',
                'quantity.required' => 'Introduzca una cantidad a comprar',
                'quantity.integer'  => 'Debe introducir una cantidad válida',
                'quantity.*.max'  => 'Se ha superado el límite máximo de tickets por persona',
                'conditions.required_if'  => 'Debe aceptar los Términos y Condiciones',
                'comission.required'  => 'Debe seleccionar el método de pago',
            ];
    }

    public function rules()
    {

        return [
            'option.*'      =>  [
                                    'required_if:logintype,register',
                                    'nullable',
                                    'integer',
                                ],
            'quantity.*'    =>  [
                                    'required',
                                    'nullable',
                                    'integer',
                                ],
            'conditions'    =>  [
                                    'required_if:logintype,register',
                                    'nullable',
                                ],
            'comission'     =>  [
                                    'required',
                                ],
        ];
    }
}

In your controller, you can inject the App\Http\Requests\YourRequestClassName to the method.

use App\Http\Requests\YourRequestClassName;

public function registerAction(YourRequestClassName $request)
    {
        //rest of the controller code

Upvotes: 0

Bibhudatta Sahoo
Bibhudatta Sahoo

Reputation: 4894

You can achieve this by adding the extra comment to the validator.
Just do like this

$validator = Validator::make($request->all(), [
    'option.*' => 'required|integer',
    'quantity.*' => 'required|integer',
    'comission' => 'required',
],[
    'option.integer' => 'Debe introducir una opción válida',
    'quantity.required' => 'Introduzca una cantidad a comprar',
    'quantity.integer'  => 'Debe introducir una cantidad válida',
    'quantity.*.max'  => 'Se ha superado el límite máximo de tickets por persona',
    'conditions.required'  => 'Debe aceptar los Términos y Condiciones',
    'comission.required'  => 'Debe seleccionar el método de pago',
]);
$validator->sometimes('conditions', 'required', function($request){
    return $request->input('logintype') == 'register';
});

It will validated your input fields and give your define error message check thisenter image description here

And you can also add multiple field by array

$validator->sometimes(['conditions','option'], 'required', function($request){
    return $request->input('logintype') == 'register';
});

Check this https://laravel.com/docs/5.5/validation#conditionally-adding-rules

Upvotes: 3

Related Questions