如果我理解正确,您正在尝试在两个表中级联软删除?
我认为使用ON UPDATE CASCADE不是正确的方法。我会尝试解释一下原因...
要尝试这样做,您需要创建外键到复合键的关系。
也就是说,您需要将(events.user_id和deleted_at)链接到(user.id和delete_at)。更改其中一个,它将更新另一个。
首先,您需要向已删除的列添加默认规则,因为您无法链接空值。
因此,在两个表的迁移中添加以下内容...
$table->softDeletes()->default('0000-00-00 00:00:00');
在用户表中使用'id'和'deleted_at'添加唯一键
Schema::table('users; function($table) {
$table->unique(array('id','deleted_at'))
});
然后在事件表中创建一个外键,如下所示(链接到唯一键)
Schema::table('events', function($table) {
$table->foreign(array('user_id','deleted_at'),'events_deleted_at_foreign_key')->
}->references(array('id','deleted_at'))->on('users')->onUpdate('CASCADE'));
运行此代码,您现在应该发现如果您软删除用户,则会软删除其事件。
但是,如果您现在尝试软删除事件,则会在外键约束上失败。你可能会问为什么!?
好吧,您正在使用两个表中的id、deleted_at创建父子关系。更新父项将更新子项。关系不会断开。但是,如果您更新子项,则关系现在已经断开,使子项成为表中的孤儿。这将导致外键约束失败。
这是一个冗长的回答,但希望能够清楚地解释为什么你试图使用ON UPDATE CASCADE来实现的方法行不通,并且节省你大量的时间。要么进入TRIGGERS并触发一个函数来处理你想要做的事情,要么在你的应用程序中处理它。个人建议使用TRIGGERS,这样数据库仍然是自己的实体,不需要依赖任何东西来保持数据完整性。
delimiter //
创建触发器 soft_delete_child,当 db.users 表中的记录更新时,针对每一行执行以下操作:
BEGIN
IF NEW.deleted_at <> OLD.deleted_at THEN
UPDATE events SET deleted_at=NEW.deleted_at WHERE events.user_id=NEW.id;
END IF;
END;
//
注意:分隔符为 ;