1

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

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

2 回答 2

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 钩子时,您应该知道它使用延迟加载。也就是说,它只加载这些被询问的模型字段,而不是全部。

例如,如果您的网格仅包含街道、房屋和名称列,则 afterLoad 将仅加载这三个字段。Flat,territory_id 和 number 无论如何都是空的。因此,所需的功能不会完全以这种方式工作。同样适用于使用 addExpression + 回调字段。

于 2012-09-18T10:41:36.680 回答
0

在以前的版本(4.1)中,钩子已经在框架中,并且函数在调用时什么也不做,除非您在模型中覆盖它们。

我假设这在 4.2 中是相同的,beforeModify、beforeInsert 和 beforeDelete 只需要在模型中定义并在其中添加您需要的任何逻辑 - 这包括添加可能具有计算字段或 php 的其他模型来执行一些 calcs 和 dsql 语句填充。

于 2012-09-17T12:22:53.067 回答