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

$user->delete();

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

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

最好是在模型类内部。


当前回答

用户模型中的关系:

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

删除相关记录:

$user = User::find($id);

// delete related   
$user->photos()->delete();

$user->delete();

其他回答

用户模型中的关系:

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

删除相关记录:

$user = User::find($id);

// delete related   
$user->photos()->delete();

$user->delete();

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

在你的用户模型中。

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

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

    $result = parent::delete();

    \DB::commit();

    return $result;
}

你可以使用这种方法作为替代。

将会发生什么,我们采取与用户表相关联的所有表和删除相关的数据使用循环

$tables = DB::select("
    SELECT
        TABLE_NAME,
        COLUMN_NAME,
        CONSTRAINT_NAME,
        REFERENCED_TABLE_NAME,
        REFERENCED_COLUMN_NAME
    FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE
    WHERE REFERENCED_TABLE_NAME = 'users'
");

foreach($tables as $table){
    $table_name =  $table->TABLE_NAME;
    $column_name = $table->COLUMN_NAME;

    DB::delete("delete from $table_name where $column_name = ?", [$id]);
}

或者你也可以这样做,只是另一个选择:

try {
    DB::connection()->pdo->beginTransaction();

    $photos = Photo::where('user_id', '=', $user_id)->delete(); // Delete all photos for user
    $user = Geofence::where('id', '=', $user_id)->delete(); // Delete users

    DB::connection()->pdo->commit();

}catch(\Laravel\Database\Exception $e) {
    DB::connection()->pdo->rollBack();
    Log::exception($e);
}

注意,如果你没有使用默认的laravel db连接,那么你需要执行以下操作:

DB::connection('connection_name')->pdo->beginTransaction();
DB::connection('connection_name')->pdo->commit();
DB::connection('connection_name')->pdo->rollBack();
$table->foreignId('user_id')->constrained('user')->cascadeOnDelete();

or

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