我正在使用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无法删除或更新父行:外键约束失败(
ConversationObserver
。shop
,CONSTRAINTconversation_users
外部密钥({{ 1}})参考conversation_users_conversation_id_foreign
(conversation_id
))(SQL:从conversations
删除,其中id
。conversations
= 18和conversations
。{ {1}}不为空)
上面的代码中,使用观察者(我想避免删除订单观察者内部的所有与对话相关的事情)失败了。有想法吗?
答案 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