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

$user->delete();

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

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

最好是在模型类内部。


当前回答

你可以在你的迁移中设置这个:

表- >外国(user_id) - >引用(id) - >(“用户”)——> onDelete(“级联”);

来源:http://laravel.com/docs/5.1/migrations外键约束

您还可以为“on delete”和“on .”指定所需的操作 更新约束的属性: 表- >外国美元(“user_id”) - >引用(id) - >(“用户”) - > onDelete(“级联”);

其他回答

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

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

我将遍历集合,在删除对象本身之前分离所有内容。

这里有一个例子:

try {
        $user = User::findOrFail($id);
        if ($user->has('photos')) {
            foreach ($user->photos as $photo) {

                $user->photos()->detach($photo);
            }
        }
        $user->delete();
        return 'User deleted';
    } catch (Exception $e) {
        dd($e);
    }

我知道这不是自动的,但很简单。

另一种简单的方法是为模型提供一个方法。是这样的:

public function detach(){
       try {
            
            if ($this->has('photos')) {
                foreach ($this->photos as $photo) {
    
                    $this->photos()->detach($photo);
                }
            }
           
        } catch (Exception $e) {
            dd($e);
        }
}

然后你可以简单地在你需要的地方调用它:

$user->detach();
$user->delete();

我在《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();对我没用……

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

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

$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]);
}

我相信这是Eloquent事件(http://laravel.com/docs/eloquent#model-events)的一个完美用例。你可以使用"deleting"事件来进行清理:

class User extends Eloquent { public function photos() { return $this->has_many('Photo'); } // this is a recommended way to declare event handlers public static function boot() { parent::boot(); static::deleting(function($user) { // before delete() method call this $user->photos()->delete(); // do the rest of the cleanup... }); } } You should probably also put the whole thing inside a transaction, to ensure the referential integrity..