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

Php laravel链接IsForceDelete()事件(在观察者上),php,laravel,relational-database,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

我正在使用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();
}
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();
    }
}
对话:

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();
}
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();
    }
}
我现在尝试删除所有对话,以防订单被“永久”删除

OrderObserver:

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();
}
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();
    }
}
对话观察者:

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();
}
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();
    }
}
似乎根本没有触发
ConversationObserver
deleting
事件。 相反,我得到了一个例外:

SQLSTATE[23000]:完整性约束冲突:1451无法删除或更新父行:外键约束失败(
shop
conversation\u users
,constraint
conversation\u users\u conversation\u id\u foreign
外键(
conversation\u id
)引用
conversations
id
)(SQL:delete from
conversations
,其中
conversations
order\u id
=18且
conversations
order\u id
不为空)


上面我的代码中有什么地方失败了,使用观察者(我想避免删除order observer本身中所有与对话相关的内容)。有什么想法吗?

这可能与您如何在原始对话模型上调用delete有关

调用
$something->conversations()->delete()
时,您只执行SQL,因此不会触发您的删除事件。按照Laravel关系的工作方式,
$something->conversations()
只需拉动一个查询生成器类,因此您可以在其上使用任何查询生成器函数

从另一个角度考虑:如果您调用
$something->conversations
(在conversation字段中没有括号),这是非常不同的。这将从数据库中提取您的对话对象,并将它们放在集合中给您。这就是为什么您调用
delete()
在每一个屏幕上,都会触发删除事件

查看您对对话模型的拉动,以及在删除之前您是如何获得它们的。如果有上述方法之一,请尝试更改它以解决您的问题


关于这一点,有很多提要可能有助于详细解释。请尝试其中一种。

当您调用与
()
的关系时,它会返回您的查询生成器实例,而不是雄辩的模型集合;当您调用它时,不使用
()
它将返回集合,然后通过集合
映射
您可以逐个调用所有集合的forceDelete方法

雄辩的事件只有在检索模型然后调用方法时才起作用

User::where('id',1)->delete();
不会触发
删除和
删除
,因为您永远不会从数据库中获取模型,所以没有任何事件绑定它的等价物
\DB::table('users')->where('id',1)->delete();

但是当您调用
User::where('id',1)->first()->delete();
User::find(1)->delete()时
现在,当您首先通过从数据库获取数据创建模型时,将触发
删除
删除
的雄辩事件,然后注册绑定到此模型的任何事件,当您调用delete时,将触发其事件

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

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

我建议你重新措辞这个问题,以避免在“主要基于意见”的问题上获得反对票。“最优雅”的问题可能是意见/辩论的问题,这在Stack Overfow中是不可取的(如果你不熟悉,请参阅中关于提问的主题).我知道集合和有说服力的对象之间的区别,但使用
$conversation->messages()->forceDelete()时;
是基于雄辩的对象的。是的,一切都是这样。在这种情况下,是对象的类型造成了不同。但是我很困惑-你是通过上面的评论删除消息,然后也希望在观察者中删除消息吗?如果是这样,那可能是你的问题。对话观察者不会在删除消息时触发链。如果是出于某种原因,那么消息可能已经消失并创建失败。您这里有一些潜在的问题,希望可以很容易地解决。
$order->conversation->forceDelete();
解决了它。因为与会话的关系是类型
hasOne
没有返回任何集合(意思是
map
不起作用)。