2010-03-30 51 views
3

我讀了很多帖子,我發現了很多有關如何獲取保存插入vs更新的變體,但無法找到適合我的東西。學說保存方法更新/插入基於唯一字段

我猜如果preSave()正在通過save()自動執行(如果存在),那麼preSave就是要走的路。

columns: 
    email: 
    type: string(255) 
    unique: true 
    email: true 

我需要保存(),以檢查是否已備案的設置是唯一 如果是這樣,以檢查是否在這種情況下,電子郵件地址字段中的數據是唯一的。 根據該信息決定插入或更新已更改的已發佈字段。

回答

0
public function preSave($event) 
    { 
     if (!$this->isUniqueEmail()) { 
      $event->skipOperation(); 
     } 
    } 

但我建議你使用驗證器。

+0

這將阻止它被插入,而是跳過操作我喜歡它來更新字段。 – RoboTamer 2010-04-01 23:32:28

0

我想弗拉基米爾的答案是正確的,你只需要在skipOperation之前添加更新邏輯。

public function preSave($event) 
{ 
    if (!$this->isUniqueEmail()) { 
     // update logic 

     $event->skipOperation(); 
    } 
} 

對不起,但我不能評論弗拉基米爾的答案。

1

只需添加更多的邏輯,就可以有更好的方式來做到這一點,但這對我很有用。

public function preInsert($event) { 
    if ($this->state() == Doctrine_Record::STATE_TDIRTY) { 
      $r == findRecordInDatabaseUsingThis(); 
      $this->assignIdentifier($r->id); 
      $this->refresh(); 
      $this->state(Doctrine_Record::STATE_CLEAN); // STATE_DIRTY to do an update, this will just use the existing record without updating 
      $event->skipOperation(); 
     } 
    } 
} 
0

我剛剛遇到類似情況後發現了這個問題。 @彼得的回答幾乎是我在尋找的,但我已經添加了一些變化。

/** 
* Check if identical record exists before (re)inserting 
* @param \Doctrine_Event $event 
* @return void 
*/ 
public function preInsert(\Doctrine_Event $event) 
{ 
    $existing = $this->getTable()->findOneBy('email', $this->email); 
    if ($existing) { 
     $this->assignIdentifier($existing->id); 
     $this->hydrate($existing->toArray()); 
     $this->state(self::STATE_CLEAN); 
     $event->skipOperation(); 
    } 
} 

使用hydrate()代替refresh()意味着你執行少1個SELECT查詢。

我知道你很可能有這個問題的答案(至少我希望你有),但我想我會爲其他人提供同樣問題的解決方案。

我也刪除if ($this->state() === self::STATE_TDIRTY)作爲preInsert()僅適用於TDIRTY記錄

0

我知道我有點晚了這裏,但我發現在谷歌這個職位,而我試圖在preInsert鉤來更新場。 我不能這樣做,因爲你的目標只是刷新學說記錄,而不是在數據庫中更新它(根據我的理解^^)

要在數據庫中執行更新,我不得不使用lollowing代碼(我很驚訝,我不得不再次調用「save」)

public function preInsert(Doctrine_Event $event) 
{ 
    /* @var $weighSameDate Doctrine_Collection */ 
    $weighSameDate = Doctrine::getTable('BiometryWeightData') 
     ->createQuery() 
     ->where('user_id=?', $this->getUserId()) 
     ->where('date=?', $this->getDate()) 
     ->execute(); 
    if (count($weighSameDate)) { 
     /* @var $weight BiometryWeightData */ 
     $weight = $weighSameDate->getFirst(); 
     if ($weight->getWeight() != $this->getWeight()) { 
      $previous = clone $this; 
      $this->assignIdentifier($weight->getId()); 
      $this->hydrate($weight->toArray()); 
      $this->setWeight($previous->getWeight()); 

      $this->state(Doctrine_Record::STATE_DIRTY); // STATE_DIRTY to do an update 
      $this->save(); 
     } 
     $event->skipOperation(); 
     return; 
    } 
    parent::preInsert($event); 
}