私は次のモデルを持っています:
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
モデルが保存を無視するようにしuseragents
Useragent.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
がこれを可能な限り透過的に処理することを望んでいます.
私が見逃しているこれを実装するより良い方法はありますか?