Laravel validation if there is a child record

Asked

Viewed 536 times

1

I wonder if there is any default validation that returns an error to the user if he tries to delete a parent record where there are children.

I have a table of vehicle types, where I register car, motorcycle, for example. I have a table of brands and a third one called marca_tipo_veiculo, which associates a brand to different types of vehicles.

so far I only do this validation that checks if the vehicle type id exists

 $request->validate([
        'id' => 'required|int|exists:tipos_veiculos,id,deleted_at,NULL',
    ]);
  • You don’t think it’s better to create a foreign key between tables?

  • The relationship is n para n in this case... In the table of marks I want to have a unique record, as I gave the example of the brand Honda, which can be both for car and bike. Or I’d have to create a composite key and duplicate the brand names

2 answers

2


You can do this by creating a custom validation rule: https://laravel.com/docs/5.8/validation#custom-validation-Rules

<?php

namespace App\Rules;

use Illuminate\Contracts\Validation\Rule;
use app\Models\ModelFilho;

class CheckChildren implements Rule
{
    /**
     * Determine if the validation rule passes.
     *
     * @param  string  $attribute
     * @param  mixed  $value
     * @return bool
     */
    public function passes($attribute, $value)
    {
        $numFilhos =  ModelFilho::where('id_pai',$value)->count();
        return $numFilhos > 0 ? false : true;
    }

    /**
     * Get the validation error message.
     *
     * @return string
     */
    public function message()
    {
        return 'The :attribute has children and couldn't be deleted.';
    }
}

And in the validation:

$request->validate([
        'id' => [ 'required', 'int', new CheckChildren ]
 ]);

You can also extend the rule "exists":

https://timacdonald.me/foreign-key-validation-rule/

0

Follow the adapted solution following example above:

<?php

namespace App\Rules;

use Illuminate\Contracts\Validation\Rule;
use App\Models\TypeVehicle;

class CheckTypeVehicleChildren implements Rule
{
    /**
     * Create a new rule instance.
     *
     * @return void
     */
    public function __construct()
    {
        //
    }

    /**
     * Determine if the validation rule passes.
     *
     * @param  string  $attribute
     * @param  mixed  $value
     * @return bool
     */
    public function passes($attribute, $value)
    {
        $childrens = TypeVehicle::with('brands')->where($attribute, $value)->first();

        return $childrens->brands()->count() > 0 ? false : true;
    }

    /**
     * Get the validation error message.
     *
     * @return string
     */
    public function message()
    {
        return 'Existem marcas associadas a este tipo de veículo';
    }
}

Controller


 public function delete(Request $request)
    {
        $request['id'] = $request->route('id');

        $request->validate([
            'id' => ['bail', 'required', 'int','exists:tipos_veiculos,id,deleted_at,NULL', new CheckTypeVehicleChildren()]
        ]);

        $typeVehicle = TypeVehicle::find($request->id);

        $typeVehicle->delete();

        return response()->json(['message' => 'Tipo de veículo deletado com sucesso!'], 200);
    }


Browser other questions tagged

You are not signed in. Login or sign up in order to post.