当我使用以下语法删除一行时:

$user->delete();

是否有一种方法来附加一个类型的回调,这样它就会自动这样做:

$this->photo()->delete();

最好是在模型类内部。


当前回答

$table->foreignId('user_id')->constrained('user')->cascadeOnDelete();

or

$table->foreignId('user_id')->constrained()->cascadeOnDelete();

其他回答

在Laravel 5.2中,文档声明这些类型的事件处理程序应该在AppServiceProvider中注册:

<?php
class AppServiceProvider extends ServiceProvider
{
    /**
     * Bootstrap any application services.
     *
     * @return void
     */
    public function boot()
    {
        User::deleting(function ($user) {
            $user->photos()->delete();
        });
    }

我甚至打算将它们移动到单独的类中,而不是闭包中,以获得更好的应用程序结构。

在我的情况下,这是相当简单的,因为我的数据库表是InnoDB与外键级联删除。

因此,在这种情况下,如果照片表包含用户的外键引用,那么您所要做的就是删除酒店,清理工作将由数据库完成,数据库将从数据库中删除所有照片记录。

有3种方法可以解决这个问题:

1. 在模型引导上使用雄辩事件(参考:https://laravel.com/docs/5.7/eloquent#events)

class User extends Eloquent
{
    public static function boot() {
        parent::boot();

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

2. 使用雄辩的事件观察者(参考:https://laravel.com/docs/5.7/eloquent#observers)

在你的AppServiceProvider中,像这样注册观察者:

public function boot()
{
    User::observe(UserObserver::class);
}

接下来,添加一个Observer类,如下所示:

class UserObserver
{
    public function deleting(User $user)
    {
         $user->photos()->delete();
    }
}

3.使用外键约束(参考:https://laravel.com/docs/5.7/migrations#foreign-key-constraints)

$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');

在定义模型迁移时最好使用onDelete级联。它负责为你删除模型的关系:

e.g.

 $table->foreign(’user_id’)
  ->references(’id’)->on(’users’)
  ->onDelete(’cascade’);

如果您碰巧发现自己正在考虑如何删除一个模型及其关系到大于3或4个嵌套关系的级别,那么您应该考虑重新定义您的模型关系。

注意:这个答案是为Laravel 3编写的。因此,在Laravel的最新版本中可能会或可能不会很好地工作。

在真正删除用户之前,您可以删除所有相关照片。

<?php

class User extends Eloquent
{

    public function photos()
    {
        return $this->has_many('Photo');
    }

    public function delete()
    {
        // delete all related photos 
        $this->photos()->delete();
        // as suggested by Dirk in comment,
        // it's an uglier alternative, but faster
        // Photo::where("user_id", $this->id)->delete()

        // delete the user
        return parent::delete();
    }
}

希望能有所帮助。