当我使用以下语法删除一行时:
$user->delete();
是否有一种方法来附加一个类型的回调,这样它就会自动这样做:
$this->photo()->delete();
最好是在模型类内部。
当我使用以下语法删除一行时:
$user->delete();
是否有一种方法来附加一个类型的回调,这样它就会自动这样做:
$this->photo()->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]);
}
其他回答
或者你也可以这样做,只是另一个选择:
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();
我在《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();对我没用……
$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();
});
}
我甚至打算将它们移动到单独的类中,而不是闭包中,以获得更好的应用程序结构。
我将遍历集合,在删除对象本身之前分离所有内容。
这里有一个例子:
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();