การลบแบบเรียงซ้อน Laravel Eloquent

ฉันใช้ Laravel 4.1 และกำลังพยายามลบแบบเรียงซ้อน ฉันกำลังดำเนินการนี้เนื่องจากวิธีการลบบางวิธีจะลบเนื้อหาที่เกี่ยวข้องที่จัดเก็บไว้ใน S3 ดังนั้นการใช้การลบแบบเรียงซ้อน DB จึงไม่เหมาะสม

สมมติว่าฉันมีโมเดลรายการซึ่งมีรูปภาพและตัวเลือกที่เกี่ยวข้องหลายตัวซึ่งมีรูปภาพดังที่แสดงด้านล่าง (ตัดให้สั้นลง)

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();
            }
        });
    }
}

หมายเหตุ : ฉันกำลังทำการลบตามที่แนะนำในคำตอบนี้

เมื่อฉันเรียก $entry->delete() มันจะลบรูปภาพและรายการเองอย่างไรก็ตามตัวจัดการการลบจะไม่ถูกเรียกใช้ในตัวเลือก (ฉันไม่เห็นผลลัพธ์ไปยังบันทึก) อย่างไรก็ตาม หากฉันใช้สิ่งต่อไปนี้ในฟังก์ชันการลบรายการทุกอย่างทำงานได้ดี

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

เหตุใด $entry->options()->delete() จึงไม่ทำงาน นี่เป็นข้อผิดพลาดใน Laravel หรือฉันทำผิดพลาด


person cubiclewar    schedule 28.03.2014    source แหล่งที่มา


คำตอบ (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
        });
    }
}

คุณสามารถใช้ "each" http://laravel.com/docs/eloquent#collections

person alioygur    schedule 28.03.2014
comment
ฉันได้ลองใช้แต่ละอันแล้ว แต่ฉันไม่คิดว่ามันจะแตกต่างจากการใช้ foreach มากนัก คุณยังคงต้องวนซ้ำแต่ละอ็อบเจ็กต์ ฉันสงสัยมากขึ้นว่าเหตุใด $entry->options()->delete จึงไม่ทำงาน - person cubiclewar; 29.03.2014

มีแพ็คเกจที่ดีที่จัดการสิ่งนี้โดยเป็นทางเลือกแทนวิธีการ Boot ด้านบนและสำหรับการลบแบบนุ่มนวล

เขียนเรื่อง: https://medium.com/asked-io/cascading-softdeletes-with-laravel-5-a1a9335a5b4d

Laravel/Lumen Soft Cascade ลบและกู้คืน https://github.com/Askedio/laravel-soft-cascade

person raison    schedule 27.06.2019