laravel链接isForceDeleting()事件(在观察者上)

时间:2019-09-14 11:36:53

标签: php laravel relational-database

我正在使用laravel观察器来确保我的相关模型始终被删除。

订单:

public function conversation()
{
    return $this->hasOne('App\Conversation');
}

对话:

public function involvedUsers()
{
    return $this->hasMany('App\ConversationUser');
}

public function messages()
{
    return $this->hasMany('App\Message')->latest();
}

我正在尝试删除所有对话,以防“永久”删除订单。

OrderObserver:

public function deleting(Order $order)
{
    if ($order->isForceDeleting()) {
        $order->conversation()->forceDelete();
    }
}

对话观察者:

public function deleting(Conversation $conversation)
{
    if ($conversation->isForceDeleting()) {
        $conversation->messages()->forceDelete();
        $conversation->involvedUsers()->forceDelete();
    }
}

deleting的{​​{1}}事件似乎根本没有触发。 相反,我得到了这个异常:

  

SQLSTATE [23000]:违反完整性约束:1451无法删除或更新父行:外键约束失败(ConversationObservershop,CONSTRAINT conversation_users外部密钥({{ 1}})参考conversation_users_conversation_id_foreignconversation_id))(SQL:从conversations删除,其中idconversations = 18和conversations。{ {1}}不为空)

上面的代码中,使用观察者(我想避免删除订单观察者内部的所有与对话相关的事情)失败了。有想法吗?

2 个答案:

答案 0 :(得分:0)

这可能与您在原始会话模型上如何调用删除有关。

调用$something->conversations()->delete()时,您仅在执行SQL ,因此不会触发您的删除事件。 Laravel关系的工作方式$something->conversations()只是拉出一个Query Builder类,因此您可以在其上使用任何Query Builder函数。

从另一个角度考虑:如果调用$something->conversations(在对话字段中不带括号),则有很大不同。这会将您的对话对象从数据库中提取出来,并以集合的形式提供给您。这就是为什么当您每次调用delete()时都会触发您的删除事件。

看看您对会话模型的请求,以及如何删除它们。如果采用上述一种方法,请尝试对其进行更改以解决您的问题。

有很多提要,可能有助于详细解释。尝试使用original 'bug' reports and the conversation around it之一。

答案 1 :(得分:0)

当您使用 navController.addOnDestinationChangedListener(new NavController.OnDestinationChangedListener() { @Override public void onDestinationChanged(@NonNull NavController controller, @NonNull NavDestination destination, @Nullable Bundle arguments) { if (destination.getId() == R.id.nav_home) { Toast.makeText(MainActivity.this, "home", Toast.LENGTH_LONG).show(); } if (destination.getId() == R.id.nav_gallery) { Toast.makeText(MainActivity.this, "nav_gallery", Toast.LENGTH_LONG).show(); } if (destination.getId() == R.id.nav_slideshow) { Toast.makeText(MainActivity.this, "nav_slideshow", Toast.LENGTH_LONG).show(); } if (destination.getId() == R.id.nav_tools) { Toast.makeText(MainActivity.this, "nav_tools", Toast.LENGTH_LONG).show(); } if (destination.getId() == R.id.nav_share) { Toast.makeText(MainActivity.this, "nav_share", Toast.LENGTH_LONG).show(); } if (destination.getId() == R.id.nav_send) { Toast.makeText(MainActivity.this, "nav_send", Toast.LENGTH_LONG).show(); } } }); 调用关系时,它会返回查询生成器实例,而不是雄辩的模型集合;当您使用()调用关系时,它将返回您的集合,然后按集合()可以一次全部调用forceDelete方法。

口才事件仅在您检索模型然后调用方法时起作用。

map这样的

不会触发User::where('id',1)->delete();deleting,因为您永远不会从数据库中获取模型,因此没有任何事件将其绑定到deleted

但是,当您调用\DB::table('users')->where('id',1)->delete();User::where('id',1)->first()->delete();时,User::find(1)->delete();deleting的雄辩事件将在您首先通过从数据库获取数据创建模型时触发,然后绑定任何事件该模型已注册,当您调用delete时将触发其事件。

在Order Observer上,您需要检索模型,然后调用forceDelete

deleted