1

私が達成したいのは次のとおりです。

モデル(または関連モデル)の他の値を使用して自動的に計算される値をデータベースに保存する必要があります。これらのモデルフックの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

これは正しい解決策のように見えます。それらの少なくとも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はこれらの3つのフィールドのみをロードします。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 に答える