doctrine save方法根据唯一字段更新/插入

时间:2010-03-30 16:02:56

标签: php doctrine

我阅读了很多帖子,我发现了很多关于如何保存插入vs更新的变体,但找不到对我有用的东西。

我猜想如果preSave()由save()自动执行(如果存在的话),那么preSave就是你的选择。

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

我需要save()来检查字段是否设置为唯一 如果是这样,检查这种情况下的电子邮件地址的字段数据是否唯一。 根据该信息决定插入或更新已更改的已发布字段。

6 个答案:

答案 0 :(得分: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();
        }
    }
}

答案 1 :(得分:0)

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

但我建议您使用验证器。

答案 2 :(得分:0)

我猜Vladimir的答案是正确的,你只需要在skipOperation之前添加更新逻辑。

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

        $event->skipOperation();
    }
}

很抱歉,但我无法评论弗拉基米尔的回答。

答案 3 :(得分:0)

如果您包含行ID,则

replace()可能会有效。

答案 4 :(得分:0)

在遇到类似的情况后,我刚刚挖出了这个问题。 @Peter的答案几乎就是我要找的,但我添加了一些变化。

/**
 * 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记录

答案 5 :(得分:0)

我知道我在这里有点晚了,但是当我试图更新preInsert钩子中的字段时,我在Google上发现了这篇文章。 我不能按照你所做的那样去做,因为你的目标只是刷新Doctrine-Record,而不是在DB中更新它(从我理解的^^)

要在DB中执行更新,我不得不使用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);
}