データベースに支援されたロガーを構築しているときに、同様の問題に直面しました。警告疲れを防ぐために、各ログ メッセージに識別コンテンツのハッシュである UID を割り当て、UID を一意のキーにしました。
当然、これには、その UID 値に一致するレコードが既に存在するかどうかを判断する必要があります (私の場合、count
そのログ レコードの値をインクリメントし、そのupdated_at
タイムスタンプに触れます)。
これと同様に、モデルクラスでオーバーライドDoctrine_Record::save()
することになりました(コードは状況により関連するように調整されています):
/** Persists the changes made to this object and its relations into the
* database.
*
* @param $conn Doctrine_Connection
* @return void
*/
public function save( Doctrine_Connection $conn = null )
{
/* Invoke pre-save hooks. */
$this->invokeSaveHooks('pre', 'save');
/* Check to see if a duplicate object already exists. */
if( $existing = $this->getTable()->findDuplicate($this) )
{
/* Handle duplicate. In this case, we will return without saving. */
return;
}
parent::save($conn);
}
UserTable::findDuplicate()
次のようになります。
/** Locates an existing record that matches the specified user's email (but
* without matching its PK value, if applicable).
*
* @param $user User
*
* @return User|bool
*/
public function findDuplicate( User $user )
{
$q =
$this->createQuery('u')
->andWhere('u.email = ?', $user->email)
->limit(1);
if( $user->exists() )
{
$q->andWhere('u.id != ?', $user->id);
}
return $q->fetchOne();
}
preSave()
モデルではなく、上書きする方がおそらくより良いアプローチであることに注意してsave()
ください。私の場合、事前保存フックが実行されるまで待たなければならなかった (UID は、私が作成した Doctrine テンプレートをsave()
使用して設定された) ため、代わりに上書きする必要がありました。