1

看起来 Model 钩子 beforeDelete 不能分层工作。让我举例说明。

class Model_User extends Model_Table{
    public $table='user';
    function init(){
        parent::init();
        $this->debug();
        $this->addField('name');
        $this->hasMany('Item');
        $this->addHook('beforeDelete',$this);
    }
    function beforeDelete($m){
        $m->ref('Item')->deleteAll();
    }
}

class Model_Item extends Model_Table{
    public $table='item';
    function init(){
        parent::init();
        $this->debug();
        $this->addField('name');
        $this->hasOne('User');
        $this->hasMany('Details');
        $this->addHook('beforeDelete',$this);
    }
    function beforeDelete($m){
        $m->ref('Details')->deleteAll();
    }
}

class Model_Details extends Model_Table{
    public $table='details';
    function init(){
        parent::init();
        $this->debug();
        $this->addField('name');
        $this->hasOne('Item');
    }
}

当我在“祖父”Model_User 上调用 delete() 时,它会尝试按预期删除所有 Item 记录,但不会从那里执行 Item.beforeDelete 钩子,并且在尝试删除 Item 之前不要删除 Details 记录。

我做错了什么?

4

1 回答 1

1

我想我至少让它适用于分层模型结构。

这是如何完成的:

class Model_Object extends hierarchy\Model_Hierarchy {
    public $table = 'object';

    function init(){
        parent::init();
        $this->debug(); // for debugging
        $this->addField('name');
        $this->addHook('beforeDelete',$this);
    }

    function beforeDelete($m) {
        // === This is how you can throw exception if there is at least one child record ===
        // if($m->ref('Object')->count()->getOne()) throw $this->exception('Have child records!');

        // === This is how you can delete child records, but use this only if you're sure that there are no child/child records ===
        // $m->ref('Object')->deleteAll();

        // === This is how you can delete all child records including child/child records (hierarcialy) ===
        // Should use loop if we're not sure if there will be child/child records
        // We have to use newInstance, otherwise we travel away from $m and can't "get back to parent" when needed
        $c = $m->newInstance()->load($m->id)->ref('Object');
        // maybe $c = $m->newInstance()->loadBy('parent_id',$m->id); will work too?
        foreach($c as $junk){
            $c->delete();
        }
        return $this;
    }

}

这里重要的事情是:
* 扩展层次结构\Model_Hierarchy 类而不是 Model_Table
* 在 beforeDelete 挂钩中使用适当的方法
* * 如果我们有孩子,则限制删除 - 抛出异常
* * deleteAll - 当你确定没有孩子/孩子时使用它记录
* * newInstance + 循环 + 删除 - 当您必须删除记录(甚至是子/子/...)层次结构时使用它

也许你们中的一些人有更好的解决方案?

于 2012-08-09T10:40:59.527 回答