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

$user->delete();

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

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

最好是在模型类内部。


当前回答

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

在你的用户模型中。

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

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

    $result = parent::delete();

    \DB::commit();

    return $result;
}

其他回答

在想要删除的模型上添加删除功能 定义模型的关系

例如在这个例子中:

/**
 * @return bool|null
 */
public function delete(): ?bool
{
    $this->profile()->delete();
    $this->userInterests()->delete();
    $this->userActivities()->delete();
    $this->lastLocation()->delete();

    return parent::delete();
}

用户模型中的关系为:

public function profile()
{
    return $this->hasOne(Profile::class, 'user_id', 'id');
}

public function userInterests()
{
    return $this->hasMany(userInterest::class, 'user_id', 'id');
}

public function userActivities()
{
    return $this->hasMany(userActivity::class, 'user_id', 'id');
}

public function lastLocation()
{
    return $this->hasOne(LastLocation::class, 'user_id', 'id');
}

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

我相信这是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..

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

or

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

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

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