当我使用以下语法删除一行时:
$user->delete();
是否有一种方法来附加一个类型的回调,这样它就会自动这样做:
$this->photo()->delete();
最好是在模型类内部。
当我使用以下语法删除一行时:
$user->delete();
是否有一种方法来附加一个类型的回调,这样它就会自动这样做:
$this->photo()->delete();
最好是在模型类内部。
当前回答
使用限制()
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');
其他回答
使用限制()
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');
在我的情况下,这是相当简单的,因为我的数据库表是InnoDB与外键级联删除。
因此,在这种情况下,如果照片表包含用户的外键引用,那么您所要做的就是删除酒店,清理工作将由数据库完成,数据库将从数据库中删除所有照片记录。
我将遍历集合,在删除对象本身之前分离所有内容。
这里有一个例子:
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();
有3种方法可以解决这个问题:
1. 在模型引导上使用雄辩事件(参考:https://laravel.com/docs/5.7/eloquent#events)
class User extends Eloquent
{
public static function boot() {
parent::boot();
static::deleting(function($user) {
$user->photos()->delete();
});
}
}
2. 使用雄辩的事件观察者(参考:https://laravel.com/docs/5.7/eloquent#observers)
在你的AppServiceProvider中,像这样注册观察者:
public function boot()
{
User::observe(UserObserver::class);
}
接下来,添加一个Observer类,如下所示:
class UserObserver
{
public function deleting(User $user)
{
$user->photos()->delete();
}
}
3.使用外键约束(参考:https://laravel.com/docs/5.7/migrations#foreign-key-constraints)
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
这里有一些完美的解决方案。
# model
public function order_item_properties()
{
return $this->hasMany(OrderItemProperty::class, 'order_id', 'id');
}
public function order_variations()
{
return $this->hasMany(OrderItemVariation::class, 'order_id', 'id');
}
# controller
$order_item = OrderItem::find($request->order_id);
$order_item->order_item_properties()->delete();
$order_item->order_variations()->delete();
$order_item->delete();
return response()->json([
'message' => 'Deleted',
]);