我在我的PHP应用程序中使用带有CodeIgniter Datamapper的InnoDB表来使用MySQL。通常,通过启动 - >删除函数调用,用户可以选择通过应用程序删除记录。当记录有子记录(一对一或一对多)时,我还希望将这些记录与父记录一起删除,如果它是由数据库中的FK约束表示的。
在这种情况下,我有2个表,项和input_lines。我已经确认两者都在使用InnoDB。每个项目都可以有许多input_line,因此input_lines有一个名为item_id的字段,该字段设置为NULL,已编入索引并具有FK约束(ON CASCADCAD DELETE和ON CASCADE UPDATE)。我已将DM配置文件中的config元素设置为
$config['cascade_delete'] = FALSE
因为在文档中它说如果你使用ON UPDATE / DELETE CASCADE,你应该这样做。但是,当用户启动$ item-> delete()方法时,只删除该项,并将与该项关联的input_line记录上的item_id字段设置为null。
我的模特看起来像这样:
class Item extends DataMapper {
public $has_many = array('labour', 'item_type', 'input_line', 'custom_item_type');
...
}
class Input_line extends DataMapper {
public $has_one = array('item');
...
}
我用cascade_delete = false和true尝试了这个,它不起作用。我知道约束有效,因为删除MySQL的记录直接按预期工作,删除子记录。
我错过了什么?为什么将FK字段设置为null而不是删除记录?
编辑1:
我决定不再调试datamapper.php(libraries目录)中的delete函数。
我注意到该函数中的代码:
// Delete all "has many" and "has one" relations for this object first
foreach (array('has_many', 'has_one') as $type)
{
foreach ($this->{$type} as $model => $properties)
{
// do we want cascading delete's?
if ($properties['cascade_delete'])
{
....
所以我var_dumped $ properties的内容,我看到了:
array (size=8)
'class' => string 'labour' (length=6)
'other_field' => string 'item' (length=4)
'join_self_as' => string 'item' (length=4)
'join_other_as' => string 'labour' (length=6)
'join_table' => string '' (length=0)
'reciprocal' => boolean false
'auto_populate' => null
'cascade_delete' => boolean true
当模型没有专门初始化的属性时,默认情况下是覆盖配置值。这似乎太明显了一个错误,所以肯定在某个地方我做错了......对吧?我真的,真的想避免黑客入侵DM核心文件......
编辑2:
我在想也许找不到配置文件,但我检查了日志,并且有条目说明Datamapper配置文件已成功加载,所以这不是问题。
答案 0 :(得分:0)
看起来没有人有任何答案。
我的解决方案是将datamapper库$ cascade_delete中的属性更改为false,因为它现在设置为true。不幸的是,我不得不求助于破解核心,但DM不会尊重我在cascade_delete配置文件中的更改,所以我别无选择。
如果有人遇到此问题并且之前遇到过此类问题,请发表评论。
答案 1 :(得分:0)
我遇到了同样的问题,但最后我只是这样做了:
$sql = "DELETE FROM EVENT WHERE event_id=".$event_id.";";
$this->db->query ($sql );
如果我们设置" ON DELETE CASCADE"对于引用event_id的外键,上面的SQL工作正常,所以我直接调用它。