我想要完成的是以下内容。
我需要在数据库中保存一些字段,该值应使用其模型(或相关模型)中的其他值自动计算。我想我应该使用这些模型钩子之一 - beforeInsert,beforeModify,afterInsert,afterModify,但是我应该怎么做呢? 此外,此字段不应更改,但在UI表单/网格中可见。
例如,
class Model_Address extends Model_Table{
public $table='address';
function init(){
parent::init();
$this->hasOne('Territory');
$this->addField('street');
$this->addField('house');
$this->addField('number');
$this->addField('name')->readonly(true); // this should be calculated on save
$this->addHook('beforeModify',$this);
}
// How to write this to set name=street+house+number+territory.name ???
function beforeModify($m){
$ter_name = $m->ref('Territory')->get('name');
$m['name'] = $m['street'].' '.$m['house'].' '.$m['number'].', '.$ter_name;
return $m;
}
}
编辑:
这个解决方案是否正确?它看起来有效,但我还不确定。
class Model_Address extends Model_Table{
public $table='address';
function init(){
parent::init();
$this->hasOne('Territory');
$this->addField('street');
$this->addField('house');
$this->addField('number');
$this->addField('name')->readonly(true); // this should be calculated on save
$this->addHook('beforeSave',$this);
}
function beforeSave($m){
$t=$m->ref('territory_id');
if($t->loaded()){
$m=set('name',$m->get('street').' '.$m->get('house').' '.$m->get('number').', '.$t->get('name'));
}
return $this;
}
}
答案 0 :(得分:1)
这看起来像是一个正确的解决方案。至少其中一个:)
class Model_Address extends Model_Table{
public $table='address';
function init(){
parent::init();
$this->hasOne('Territory');
$this->addField('street');
$this->addField('house');
$this->addField('number');
$this->addField('name')->readonly(true); // this should be calculated on save
$this->addHook('beforeSave',$this);
}
function beforeSave($m){
$t=$m->ref('territory_id');
if($t->loaded()){
$m=set('name',$m->get('street').' '.$m->get('house').' '.$m->get('number').', '.$t->get('name'));
}
return $this;
}
}
我也可以使用afterLoad钩子,但我决定在数据库中更好地保存这个连接值,以最大限度地减少加载时间计算。
另外,当你使用afterLoad钩子时,你应该知道它使用了延迟加载。也就是说,它只加载被询问的这些模型字段而不是所有模型字段。
例如,如果您的网格只包含street,house和name列,那么afterLoad将只加载这三个字段。无论如何,Flat,territory_id和数字都将为空。因此,期望的功能不会完全以这种方式工作。 同样适用于使用addExpression +回调字段。
答案 1 :(得分:0)
在之前的版本(4.1)中,钩子已经在框架中,并且当调用unles时,函数在模型中覆盖它们时什么都不做。
我认为这与4.2中的相同,即beforeModify,beforeInsert和beforeDelete只需要在模型中定义并添加你需要的任何逻辑 - 这包括添加可能有计算字段的其他模型或php来做一些计算和要填充的dsql语句。