Tengo un problema, ¿cómo se agrega/elimina una regla si otra regla pasa/falla?
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; }Por ejemplo, si la regla "warehouse_id" falla, no sería necesario evaluar las reglas del campo "warehouse_qty" (ya que la identificación del almacén no se encuentra en la base de datos).
O si la regla del campo "user_id" tiene éxito, se deben activar nuevas reglas, como para los campos "user_name" y "user_phone" .
¡Gracias!
Para validar un campo solo si otro pasa la validación, existen múltiples soluciones.
Desde Laravel 5.3.23; Simplemente mueva cualquier validación de campo que dependa de las reglas de otro campo, al método withValidator(...) de Controller, como:
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(); }); } Esto tiene la ventaja de simplemente usar las reglas existentes, como lo haría normalmente (en lugar de reescribir el código fuente de la regla " required ", como lo hace el enfoque a continuación).
Consulte también la publicación relacionada de Laracast .
Tenga en cuenta que si el método
rules()no está definido,withValidator(...)nunca se llama (y llamar a$this->input()puede resultar en un error de función no definida).
Desde Laravel 5.6 y posteriores podemos hacer lo siguiente:
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; }Tenga en cuenta que para que funcione lo anterior, el orden de los campos es importante, y el
closuredebe agregarse a la matriz justo después de los campos de los que depende.
-------===-------
Si bien los anteriores son enfoques personalizados (para asuntos solicitados), hacer eso para las reglas del mismo campo está integrado en Laravel.
| ) para separar las reglas.Simplemente porque se ignora cualquier regla posterior a la fallida.
Gracias a todos los que dieron sus soluciones a mi problema, en especial a Top-Master, ya que su explicación me mostró otro punto de vista.
Finalmente pude resolver mi problema, y esta es mi solución. Si alguien puede mejorar el código, bienvenido sea.
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; }