Penghapusan Bertingkat Laravel Eloquent

Saya menggunakan Laravel 4.1 dan mencoba penghapusan berjenjang. Saya melakukan ini karena beberapa metode penghapusan menghapus aset terkait yang disimpan di S3, jadi mengandalkan penghapusan kaskade DB tidak cocok.

Katakanlah saya memiliki model Entri yang memiliki gambar dan banyak Opsi terkait yang juga memiliki gambar seperti yang ditunjukkan di bawah ini (dipotong agar singkatnya).

class Entry extends Eloquent {
    public function image()
    {
        return $this->morphOne('Image', 'imageable');
    }

    public function options()
    {
        return $this->hasMany('Option');
    }

    protected static function boot() {
        parent::boot();

        static::deleting(function($entry) {
            $image = $entry->image;
            if($image !== null) {
                $image->delete();
            }

            $entry->options()->delete()
            //Option::where('entry_id', $entry->id)->delete(); This also doesn't work
        });
    }
}

class Option extends Eloquent {

    public function entry()
    {
        return $this->belongsTo('Entry');
    }

    public function image()
    {
         return $this->morphOne('Image', 'imageable');
    }

    protected static function boot() {
        parent::boot();

        static::deleting(function($option) {
            Log::info('Trying to delete an option object');
            $image = $option->image;

            if($image !== null) {
                $image->delete();
            }
        });
    }
}

Catatan : Saya melakukan penghapusan seperti yang direkomendasikan dalam jawaban ini.

Ketika saya memanggil $entry->delete() itu akan menghapus gambar dan entri itu sendiri namun penangan penghapusan tidak pernah dipanggil pada opsi (saya tidak melihatnya ditampilkan ke log). Namun jika saya menggunakan yang berikut ini dalam fungsi penghapusan Entri, semuanya berfungsi dengan baik.

foreach($entry->options as $option) {
    $option->delete();
}

Mengapa $entry->options()->delete() tidak berfungsi? Apakah ini bug di Laravel atau saya melakukan kesalahan.


person cubiclewar    schedule 28.03.2014    source sumber


Jawaban (2)


class Entry extends Eloquent {
    public function image()
    {
        return $this->morphOne('Image', 'imageable');
    }

    public function options()
    {
        return $this->hasMany('Option');
    }

    protected static function boot() {
        parent::boot();

        static::deleting(function($entry) {
            $image = $entry->image;
            if($image !== null) {
                $image->delete();
            }

            $entry->options->each(function($option) {
                $option->delete();
            });
            //Option::where('entry_id', $entry->id)->delete(); This also doesn't work
        });
    }
}

Anda dapat menggunakan "masing-masing" http://laravel.com/docs/eloquent#collections

person alioygur    schedule 28.03.2014
comment
Saya telah mencoba menggunakan masing-masing namun menurut saya tidak jauh berbeda dengan menggunakan foreach, Anda masih perlu mengulangi setiap objek. Saya lebih penasaran mengapa $entry-›options()-›delete tidak berfungsi - person cubiclewar; 29.03.2014

Ada paket bagus yang menangani ini sebagai alternatif dari metode Boot di atas dan untuk penghapusan sementara.

Penulisan: https://medium.com/asked-io/cascading-softdeletes-with-laravel-5-a1a9335a5b4d

Laravel/Lumen Soft Cascade Hapus & Pulihkan https://github.com/Askedio/laravel-soft-cascade

person raison    schedule 27.06.2019