Автоматическое удаление дочерних моделей

У меня есть три модели: User has-many Post has-many Comment. Когда я удаляю пользователя, я хочу, чтобы все его связанные сообщения автоматически удалялись, а также комментарии, связанные с этими сообщениями. Для этого у меня есть следующий код в моделях User и Post:

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

    static::deleting(function($user) {
        $user->posts()->delete();
    });
}

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

    static::deleting(function($post) {
        $post->comments()->delete();
    });
}

Когда я удаляю пользователя, все его сообщения удаляются, однако комментарии сохраняются. Почему это происходит?


person Alex Lomia    schedule 03.06.2016    source источник
comment
Вы определили каскадное удаление при миграции?   -  person Amarnasan    schedule 03.06.2016
comment
в вашей миграции добавьте это ->onDelete('cascade');   -  person Achraf Khouadja    schedule 03.06.2016
comment
@AchrafKhouadja На самом деле onDelete ('каскад')   -  person Amarnasan    schedule 03.06.2016
comment
уже исправлено, просто ошибка, все равно спасибо   -  person Achraf Khouadja    schedule 03.06.2016
comment
Этот подход не зависит от onDelete('cascade')   -  person Alex Lomia    schedule 03.06.2016
comment
В методе boot() вашей модели Post у вас есть $user в качестве параметра обратного вызова. Необходимо изменить на $post.   -  person Jonathon    schedule 03.06.2016
comment
@Jonathon Спасибо, отредактировано   -  person Alex Lomia    schedule 04.06.2016


Ответы (2)


Лучше, если для этого вы будете использовать схему базы данных. Это быстрее и не будет ошибок «максимального уровня вложенности функций»

public function up()
{
    Schema::create('comments', function(Blueprint $table)
    {
        $table->increments('id');
        $table->integer('post_id');
        $table->string('comment');
    });

    Schema::table('comments', function(Blueprint $table){
        $table->foreign('post_id')->references('id')->on('posts')->onDelete('cascade');
    });
}
person Sangar82    schedule 03.06.2016
comment
Я пытаюсь это сделать, но получаю General error: 1215 Cannot add foreign key ошибку - person Alex Lomia; 04.06.2016
comment
см .: stackoverflow.com/a/37454021/1171049 Вам необходимо сначала выполнить миграцию сообщений, а затем перенос комментариев. . Я надеюсь, что это помогает - person Sangar82; 04.06.2016

Вы пробовали делать дальше?

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

    static::deleting(function($user) {
        foreach ($user->posts() as $post)
        {
            $post->comments()->delete();
        }            
        $user->posts()->delete();

    });

Кстати, это должно быть в схеме базы данных при каскаде удаления, и вам не понадобится код модели для удаления дочерних элементов.

person KuKeC    schedule 03.06.2016
comment
Попробую это сделать, но здравый смысл подсказывает, что всякий раз, когда модель удаляется, должен срабатывать ..::deleting() метод. Интересно, почему этого не происходит. Каскадное удаление требует, чтобы InnoDB был выбран в качестве механизма БД для каждой таблицы. - person Alex Lomia; 03.06.2016
comment
Хорошо, попробуй сделать это. Я обновил свой ответ, так как сначала нужно удалить все комментарии, а затем сообщения для комментариев. Для удаления вам нужно пройти через все сообщения в foreach, а затем удалить каждый комментарий по отдельности. - person KuKeC; 03.06.2016
comment
Лучше использовать схему базы данных, это быстрее. У меня были проблемы с этим кодом с ошибкой: «Достигнут максимальный уровень вложенности функции« 100 », прерывание!» - person Sangar82; 03.06.2016