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

$user->delete();

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

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

最好是在模型类内部。


当前回答

最好为此重写delete方法。这样,您就可以在delete方法本身中合并DB事务。如果你使用事件方式,你将不得不覆盖你的删除方法调用与DB事务每次你调用它。

在你的用户模型中。

public function delete()
{
    \DB::beginTransaction();

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

    $result = parent::delete();

    \DB::commit();

    return $result;
}

其他回答

我在《Laravel 8》中使用了这种方法:

public static function boot() {

    parent::boot();
    
    static::deleted(function($item){
        $item->deleted_by = \Auth::id(); // to know who delete item, you can delete this row
        $item->save();  // to know who delete item, you can delete this row
        foreach ($item->photos as $photo){
            $photo->delete();
        }
    });
}

public function photos()
{
    return $this->hasMany('App\Models\Photos');
}

注意:在此语法中删除$user->photos()->delete();对我没用……

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

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

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

or

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

使用限制()

Laravel 7之后,有了新的foreignId()和constrained()方法来定义数据库中的关系约束。可以在这些方法上使用OnDelete()方法自动删除相关记录。

古老的风格

$table->unsignedBigInterer('user_id');

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

新风格

$table->foreignId('user_id')
      ->constrained()
      ->onDelete('cascade');

要详细说明所选的答案,如果关系也有必须删除的子关系,则必须首先检索所有子关系记录,然后调用delete()方法,以便正确地触发它们的删除事件。

您可以使用更高阶的消息轻松实现这一点。

class User extends Eloquent
{
    /**
     * The "booting" method of the model.
     *
     * @return void
     */
    public static function boot() {
        parent::boot();

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

你也可以通过只查询关系ID列来提高性能:

class User extends Eloquent
{
    /**
     * The "booting" method of the model.
     *
     * @return void
     */
    public static function boot() {
        parent::boot();

        static::deleting(function($user) {
             $user->photos()->get(['id'])->each->delete();
        });
    }
}