Symfony $ form-> save()插入一行而不是更新它

时间:2013-05-04 04:25:58

标签: php forms symfony-1.4 propel

我正在试图解释为什么我的表单试图插入一行而不是更新它,但我不知道,这是代码:

//This function is the one that displays the form
public function executeIndex(sfWebRequest $request) {

...

    $evrescrit = new Criteria();
    $evrescrit->addSelectColumn(EvaluacionResumenPeer::STATUS);
    $evrescrit->addSelectColumn(EvaluacionResumenPeer::RELEVANCE);
    $evrescrit->addSelectColumn(EvaluacionResumenPeer::QUALITY);
    $evrescrit->addSelectColumn(EvaluacionResumenPeer::COMMENT);
    $evrescrit->add(EvaluacionResumenPeer::RESUMEN_ID, $this->resumen->getId());

    $this->form = new EvaluacionResumenForm(EvaluacionResumenPeer::retrieveByPK($this->resumen->getId()), array('criteria' => $evrescrit));
    //$this->form = new EvaluacionResumenForm(EvaluacionResumenPeer::retrieveByPK($this->resumen->getId()));
}


 //The form, I'm using the Base but unsetting some columns, PK and FK.
class EvaluacionResumenForm extends BaseEvaluacionResumenForm {

public function configure() {
    unset(
            $this['created_at'], $this['updated_at'], $this['evaluador_id'], $this['resumen_id']
    );
}

}


//This is where the form submits
public function executeEdit(sfWebRequest $request) {

    $user = $this->getUser()->getGuardUser();
    $this->forward404Unless($user);
    $this->form = new EvaluacionResumenForm();

    if ($request->isMethod(sfRequest::POST)) {
        $this->processEdit($request, $this->form);
    }
}

public function processEdit(sfWebRequest $request, sfForm $form) {

    $this->form->bind($request->getParameter($form->getName()));
    //$this->form->bind($request->getPostParameter($request->getPostParameter('status')));

    $errors = $this->form->getErrorSchema()->getErrors();
    if (count($errors) > 0) {
        foreach ($errors as $name => $error) {
            echo $name . ': ' . $error . '<br>';
            echo $request->getParameter('evaluacion_resumen[resumen_id]');
        }
    }

    if ($this->form->isValid()) {
        $this->form->save();
        $this->getUser()->setFlash('notice', 'Sus modificaciones han sido grabadas.');
        $this->redirect('@resumenes_asignados');
    }
}

在模板中,我使用它来渲染表单:

<?php echo $form->renderHiddenFields(); ?>
<?php echo $form; ?>

我提交表单时遇到的错误(我从数据库中获取值,并使用此表单更新)是这样的:

Unable to execute INSERT statement. [wrapped: SQLSTATE[HY000]: General error: 1452 Cannot add or update a child row: a foreign key constraint fails (`abstracts/evaluacion_resumen`, CONSTRAINT `evaluacion_resumen_FK_1` FOREIGN KEY (`resumen_id`) REFERENCES `resumen` (`id`))]

我真的不知道为什么它会尝试插入新行,我需要更新现有的行。

感谢。

1 个答案:

答案 0 :(得分:1)

这是因为executeEdit()函数中的下面一段代码。

$this->form = new EvaluacionResumenForm();

BaseEvaluacionResumenForm继承自sfFormPropelsfFormPropel将Propel对象作为其构造函数中的第一个参数。如果没有传递任何对象(如您的情况),它将使用getModelName()函数来确定此表单中模型中的哪个对象使用并创建一个新对象(见下文)。

// \lib\vendor\....\sfFormPropel.class.php
public function __construct(BaseObject $object = null, $options = array(), $CSRFSecret = null)
  {
    $class = $this->getModelName();
    if (is_null($object))
    {
      $this->object = new $class();
    }

因此,当表单保存时,它会保存一个新对象,这就是您获取插入而不是更新的原因。

你想做这样的事情:

// This is where the form submits
// Example url, http://mysite.com/moduleName/edit/id/:id
public function executeEdit(sfWebRequest $request) {

    $user = $this->getUser()->getGuardUser();
    $this->forward404Unless($user);

    // Get the primary key of the object we want to use or forward 404
    $this->forward404Unless($id = $request->getParameter('id'), "Required parameter 'id' must be present in request");

    // Retrieve the object from the database using the id or forward 404
    $this->forward404Unless($er = EvaluacionResumenPeer::retrieveByPK($id), sprintf("No object could be retrieved by %s", $id));

    $this->form = new EvaluacionResumenForm($er);

    if ($request->isMethod(sfRequest::POST)) {
        $this->processEdit($request, $this->form);
    }
}

作为附加检查,当对象不是新的时,您可以在表单模板中更改请求的类型,如下所示。这样可以确保您不会在编辑操作中意外插入任何新对象。

// apps\appName\modules\moduleName\templates\editSuccess.php
if (!$form->isNew()): ?>
    <input type="hidden" name="sf_method" value="PUT" />
<?php endif ?>

然后在你的executeEdit()函数中。如果请求的类型为POST,则更改检查行以检查它是否为PUT。

if ($request->isMethod(sfRequest::PUT)) {