mercredi 5 septembre 2018

Laravel custom delete method via pivot table

I have a pivot table between 'ingredients' and 'images'. On the Image model I have a custom delete method which deletes the image from the s3 storage. The issue is that if I use onDelete('cascade') on the pivot table foreign keys the delete() method won't get fired. I tried a workaround but with no success. My Ingredient model:

class Ingredient extends Model
{
    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = ['ingredient_category_id', 'name', 'units', 'price'];

    ///////////////////
    // Relationships //
    ///////////////////
    public function images() {
        return $this->belongsToMany(Image::class, 'ingredient_images')->withTimestamps();
    }

    /////////////
    // Methods //
    /////////////
    public function delete()
    {
        $this->images()->delete();
        $this->images()->detach();

        return parent::delete();
    }
}

My Image model:

class Image extends Model
{
    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = ['title', 'path'];

    ///////////////////
    // Relationships //
    ///////////////////
    public function ingredients() {
        return $this->belongsToMany(Ingredient::class, 'ingredient_images')->withTimestamps();
    }

    /////////////
    // Methods //
    /////////////
    public function delete()
    {
        $this->ingredients()->detach();

        Storage::disk('s3')->delete($this->path);

        return parent::delete();
    }
}

My pivot table (ingredient_images):

public function up()
{
    Schema::create('ingredient_images', function (Blueprint $table) {
        $table->increments('id');
        $table->unsignedInteger('ingredient_id');
        $table->foreign('ingredient_id')->references('id')->on('ingredients');
        $table->unsignedInteger('image_id');
        $table->foreign('image_id')->references('id')->on('images');
        $table->timestamps();
    });
}

I tried on the Ingredient model to have a custom delete() method which calls the images() delete method, the issue is that the method delete() from the Image model is not called (which is supposed to remove the image from the storage as well detach it from the pivot table.

When I try:

Ingredient::findOrFail($ids)->images()->delete()
Ingredient::findOrFail($ids)->delete()

I get:

Integrity constraint violation: 1451 Cannot delete or update a parent row: a foreign key constraint fails



via Chebli Mohamed

Aucun commentaire:

Enregistrer un commentaire