0

私は次のモデルを持っています:

class Useragent extends AppModel {

    public $validate = array(
        'useragent' => array(
            'unique' => array(
                'rule' => 'isUnique',
            ),
        )
    );

    public $hasMany = array(
        'LoggedActions'
    );
}

class LoggedAction extends AppModel {

    public $belongsTo = array(
        'Useragent' => array(
            'className' => 'Useragent',
        )
    }
} 

これら 2 つのモデルの目的は、サイト訪問者の IP アドレスとユーザー エージェントを追跡することです。すべての行で長いユーザー エージェント文字列を繰り返したくないので、テーブルを正規化する必要があります。

訪問者を追跡する場合、コードは次のようになります。

    $data=array(
        'LoggedAction'=>array(
            'ip_address' => 3232235521, //INET_ATON format
        ),
        'Useragent'=>array(
            'useragent'=>'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36'
        )
    );

    $this->LoggedAction->saveAssociated($data);

ユーザーエージェントがテーブルに既に存在する場合、Useragentモデルが保存を無視するようにしuseragentsUseragent.useragentます(保存を実行するときに不明ではなく、フィールドのみに基づいてUseragent.id)。

Useragent最初に を処理し、次に を処理することで、これをコントローラーに実装できることを私は知っていLoggedActionます。ただし、モデルにはこれを透過的に処理してもらいたいと思います。

  • Useragent::beforeSave()何も保存されないため、レコードが存在する場合に false を返しても機能しません。
  • をデータベースから取得した既存のレコードに置き換えるUseragent['id']Useragent::beforeSave()id検証されません。検証ルールを削除すると、 がスローされIntegrity constraint violation: 1062 Duplicate entry '1' for key 'PRIMARY'ます。

オプションは、保存操作を無視するようにメソッドをオーバーライドするUseragent::save()Useragent->idことですが、データベースからフェッチされたレコードの を設定しid、配列を返します (通常の保存と同じように)。ただし、これが他の機能を壊すかどうかはわかりません.

別のオプションはLoggedAction::saveWithUseragent()、説明した機能を実装する のようなメソッドを作成することです。しかし、私が言ったように、私はモデルUseragentがこれを可能な限り透過的に処理することを望んでいます.

私が見逃しているこれを実装するより良い方法はありますか?

4

1 に答える 1

0

私は最終的にオーバーライドすることにしましたUseragent::save()

これが私のUseragentクラスの外観です。

class Useragent extends AppModel
{

    public $displayField = 'useragent';

    public $hasMany = array(
        'LoggedActions'
    );


    public function save($data = null, $validate = true, $fieldList = array()){

        if ($useragent=$this->findByUseragent($data['useragent'])){
            $this->id=$useragent[$this->alias]['id'];
            return($useragent);
        }
        return parent::save($data,$validate,$fieldList);
    }
}

これまでのところ問題はありません。

他のモデルに関連付けられたタグにも同じアプローチを使用できます。

于 2015-12-11T16:52:22.303 に答える