Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

625
Visualizações
Validate a field only if another one passes validation (in Laravel 8)

I have a problem, how do you add / remove a rule if another rule passed/fails?

public function rules()
{
    $rules = [
        'description' => 'required|unique:orders,description',
        'user_id' => 'required|unique:users,id',
        'supplier_id' => 'required',
        'warehouse_id' => 'required|unique:warehouse,id',
        'warehouse_qty' => 'required'


    ];
    
    return $rules;
}

For example, if the "warehouse_id" rule fails, it would not be necessary to evaluate the "warehouse_qty" field's rules (since the warehouse id is not found in the db).

Or if the "user_id" field's rule succeeds, new rules should be activated, like for "user_name" and "user_phone" fields.

Thanks!

over 4 years ago · Santiago Trujillo
2 Respostas
Responde à pergunta

0

To validate a field only if another passes validation, there are multiple solutions.

Approach #2 (recommended)

Since Laravel 5.3.23; Simply move any field validation that depends on another field's rules, into Controller's withValidator(...) method, like:

use Illuminate\Support\Facades\Validator;

// ...

public function withValidator($validator)
{
    $validator->after(function ($validator) {
        // Skip if any previous field was invalid.
        if ($validator->failed()) return;

        // Actual validation (for fields depending on previous).
        Validator::make($this->input(), [
            'warehouse_qty' => ['required']
        ])->validate();
    });
}

This has the advantage of simply using existing rules, as you would normally (instead of rewriting the "required" rule's source-code, which the below approach does).

See also related Laracast post.

Note that if rules() method is not defined, withValidator(...) is never called (and calling $this->input() may result in function not defined error).

Approach #1 (Old answer)

Since Laravel 5.6 and later we can do below:

use Illuminate\Support\Facades\Validator;

// ...

public function rules()
{
    $result = [
        // ...
        'warehouse_id' => 'required|unique:warehouse,id',
    ];

    if (Validator::make($this->input(), $result)->passes()) {
        $result['warehouse_qty'] = [
            function ($attribute, $value, $fail) {
                if (empty($value)) {
                    $fail('The '.$attribute.' is required.');
                }
            },
        ];
    }

    return $result;
}

Note that for above to work, the fields order is important, and the closure should be added to array right after the fields it is depending on.

-------===-------

While above are custom approaches (for asked matter), doing that for rules of the same field is built-in Laravel.

  1. Adding a rule if another rule passed is easy:
    • The rules are executed from left to right.
    • Use pipe (the | character) to separate rules.
    • And, as long as rules at left pass, the later rules are added and/or executed.
  2. Removing a rule if another rule fails can be achieved by pipe as well.

    Simply because any rule after the failed one is ignored.

  3. But the reverse of above two statements is not possible:
    • We can not add and/or execute next-rule if previous fails.
    • We can not remove next-rule if previous passed.
    • At least, not without custom function.
over 4 years ago · Santiago Trujillo Relatório

0

Thanks to all who gave their solutions to my problem, especially Top-Master, since his explanation showed me another point of view.

I was finally able to solve my problem, and this is my solution. If anyone can improve the code, it is welcome.

public function rules()
{   

    $rules = [
        'description' => 'required|unique:orders,description',
        'user_id' => 'required|unique:users,id',
        'supplier_id' => 'required'
    ];
  
    $rules = $this->validateItems($rules);
    
    return $rules;
}

public function validateItems($rules){


        $rules["warehouse_id"] = ['required', 
                                  'unique:warehouse,id'];
        
        //Here I validate if the rules of the "warehouse_id" field fail or not.
        $validator = Validator::make($this->input('warehouse_id'), [
            "id" => ['required', 
                     'unique:warehouse,id']
        ]);

        //If the validation doesn't fail, the "warehouse_qty" field is added to $rule                                 
        if(!($validator->fails())){
            $rules["warehouse_qty"] = ['required'];
        }
        
    }
    return $rules;
}
over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda