如何计算和存储DB保存钩子上的一些字段值?

时间:2012-09-17 10:27:35

标签: atk4 php

我想要完成的是以下内容。

我需要在数据库中保存一些字段,该值应使用其模型(或相关模型)中的其他值自动计算。我想我应该使用这些模型钩子之一 - 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;
  }
}

2 个答案:

答案 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语句。