当我使用以下语法删除一行时:
$user->delete();
是否有一种方法来附加一个类型的回调,这样它就会自动这样做:
$this->photo()->delete();
最好是在模型类内部。
当我使用以下语法删除一行时:
$user->delete();
是否有一种方法来附加一个类型的回调,这样它就会自动这样做:
$this->photo()->delete();
最好是在模型类内部。
当前回答
这里有一些完美的解决方案。
# 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',
]);
其他回答
用户模型中的关系:
public function photos()
{
return $this->hasMany('Photo');
}
删除相关记录:
$user = User::find($id);
// delete related
$user->photos()->delete();
$user->delete();
在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();
});
}
我甚至打算将它们移动到单独的类中,而不是闭包中,以获得更好的应用程序结构。
是的,但是正如@supersan在上面的评论中所说,如果你在QueryBuilder上删除(),模型事件将不会被触发,因为我们没有加载模型本身,然后在该模型上调用delete()。
只有在模型实例上使用delete函数时,才会触发事件。
所以,有人说:
if user->hasMany(post)
and if post->hasMany(tags)
为了在删除用户时删除post标签,我们必须遍历$user->个帖子,并调用$post->delete()
Foreach ($user->posts as $post) {$post->delete();} ->这将在Post上触发删除事件
VS
$user->posts()->delete() ->这将不会在post上触发删除事件,因为我们实际上没有加载post模型(我们只运行SQL: delete *从user_id = $user->id的帖子,因此,post模型甚至没有加载)
要详细说明所选的答案,如果关系也有必须删除的子关系,则必须首先检索所有子关系记录,然后调用delete()方法,以便正确地触发它们的删除事件。
您可以使用更高阶的消息轻松实现这一点。
class User extends Eloquent
{
/**
* The "booting" method of the model.
*
* @return void
*/
public static function boot() {
parent::boot();
static::deleting(function($user) {
$user->photos()->get()->each->delete();
});
}
}
你也可以通过只查询关系ID列来提高性能:
class User extends Eloquent
{
/**
* The "booting" method of the model.
*
* @return void
*/
public static function boot() {
parent::boot();
static::deleting(function($user) {
$user->photos()->get(['id'])->each->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');