Doctrine_Record_Exception“在尝试保存表单数据时无法调用Doctrine_Core :: set()”

时间:2013-06-25 02:52:30

标签: symfony1 symfony-1.4 doctrine-1.2

我遇到了这个问题,我找不到有什么问题。我正在尝试在执行表单保存方法之前更新对象,我按照以下方式执行(我为了以防万一而编写了整个类):

class SdrivingMaquinaForm extends BaseSdrivingMaquinaForm {

    protected $current_user;

    public function configure() {
        $this->current_user = sfContext::getInstance()->getUser()->getGuardUser();

        unset($this['updated_at'], $this['created_at']);

        $this->widgetSchema['idempresa'] = new sfWidgetFormInputHidden();
        $id_empresa = $this->current_user->getSfGuardUserProfile()->getIdempresa();
        $this->setDefault('idempresa', $id_empresa);

        $this->widgetSchema['no_emisor'] = new sfWidgetFormDoctrineChoice(array('model' => 'SdrivingEmisor', 'add_empty' => 'Seleccione un Emisor', 'table_method' => 'fillChoice'));
        $this->validatorSchema['idempresa'] = new sfValidatorPass();
        $this->validatorSchema['no_emisor'] = new sfValidatorPass();
    }

    protected function doUpdateObject($values) {
        parent::doUpdateObject($values);

        if (isset($this['no_emisor'])) {
            if ($this->isNew()) {
                $sdrivingMaquinaEmisor = new SdrivingMaquinaEmisor();
                $this->getObject()->setSdrivingMaquinaEmisor($sdrivingMaquinaEmisor);
            } else {
                $sdrivingMaquinaEmisor = $this->getObject()->getSdrivingMaquinaEmisor();
            }

            $sdrivingMaquinaEmisor->setIdemisor($this->values['no_emisor']);
        }
    }
}

这是与该表单相关的schema.yml:

SdrivingMaquina:
  actAs: 
    Timestampable: ~
  columns:
    idmaquina: { type: integer(8), autoincrement: true, notnull: true, primary: true }
    idempresa: { type: integer(4), notnull: true }
    patente: { type: string(12), notnull: true }
  relations:
    Empresa: { local: idempresa, class: SdrivingEmpresa, type: one, foreignType: one, foreignAlias: MaquinaEmpresa, onDelete: CASCADE, onUpdate: CASCADE }
SdrivingMaquinaEmisor:
  actAs: 
    Timestampable: ~
  columns:
    idmaquinaemisor: { type: integer(8), primary: true, autoincrement: true }
    idmaquina: { type: integer(8), notnull: true }
    idemisor: { type: integer(8), notnull: true }
  relations:
    SdrivingEmisor: { onDelete: CASCADE, local: idemisor, foreign: idemisor, type: one }
    SdrivingMaquina: { onDelete: CASCADE, local: idmaquina, foreign: idmaquina, type: one }

正如您可能会注意到,没有多少关系。当我发送表单时,我收到此错误:

  

无法调用Doctrine_Core :: set(),第二个参数应该是一个   设置一对多引用时的Doctrine_Collection实例。

我无法找到错误的位置,所以任何帮助都将受到赞赏。我也在堆栈跟踪中注意到这一点:

at SdrivingMaquinaForm->doUpdateObject(array('idmaquina' => null, 'idempresa' => '1', 'patente' => 'TB58922', 'no_emisor' => '2'))

为什么idmaquinanull?我应该在同一时刻创造maquina我创造的价值。保存maquina后,我应该更改逻辑并更新关系值吗?在这种情况下,我如何获得最新id创建的maquina

修改 模板:_form.php

<?php use_stylesheets_for_form($form) ?>
<?php use_javascripts_for_form($form) ?>

<div class="row-fluid">
    <form action="<?php echo url_for('maquina/' . ($form->getObject()->isNew() ? 'create' : 'update') . (!$form->getObject()->isNew() ? '?idmaquina=' . $form->getObject()->getIdmaquina() . '&idempresa=' . $form->getObject()->getIdempresa() : '')) ?>" method="post" <?php $form->isMultipart() and print 'enctype="multipart/form-data" ' ?>>
        <?php if (!$form->getObject()->isNew()): ?>
            <input type="hidden" name="sf_method" value="put" />
        <?php endif; ?>
        <?php echo $form->renderHiddenFields(true) ?>
        <?php echo $form->renderGlobalErrors() ?>

        <div class="span4">
            <label><?php echo $form['patente']->renderLabel() ?></label>
            <?php echo $form['patente'] ?>
            <span class="help-block"><?php echo $form['patente']->renderError() ?></span>
        </div>
        <div class="span4">
            <label><?php echo $form['no_emisor']->renderLabel('Emisor') ?></label>
            <?php echo $form['no_emisor'] ?>
            <span class="help-block"><?php echo $form['no_emisor']->renderError() ?></span>
        </div>
        <div class="clearfix"></div>
        <p class="right-align-text marginTop">
            <button type="button" class="btn" id="cancel-btn"><?php echo __('Cancelar') ?></button>
            <input type="submit" value="<?php echo __('Guardar') ?>" class="btn btn-success" />
        </p>
    </form>

    <?php if ($sf_user->hasFlash('error')): ?>
        <div class="alert alert-error">
            <h4>Error!</h4>
            <?php echo $sf_user->getFlash('error') ?>
        </div>
    <?php endif; ?>
</div>

<script>
    $(function() {
        $('#cancel-btn').click(function() {
            history.go(-1);
            $('#myTab a[href="#<?php echo $sf_user->getFlash('activeTab', 'usuarios'); ?>"]').tab('show');
        });
    });
</script>

动作类:action.class.php

class maquinaActions extends sfActions {

    public function executeIndex(sfWebRequest $request) {
        $this->sdriving_maquinas = Doctrine_Core::getTable('SdrivingMaquina')->createQuery('a')->execute();
    }

    public function executeNew(sfWebRequest $request) {
        $this->getUser()->setFlash('activeTab', 'maquinas');
        $this->form = new SdrivingMaquinaForm();
    }

    public function executeCreate(sfWebRequest $request) {
        $this->forward404Unless($request->isMethod(sfRequest::POST));
        $this->form = new SdrivingMaquinaForm();
        $this->processForm($request, $this->form);
        $this->setTemplate('new');
    }

    public function executeEdit(sfWebRequest $request) {
        $this->forward404Unless($sdriving_maquina = Doctrine_Core::getTable('SdrivingMaquina')->find(array($request->getParameter('idmaquina'), $request->getParameter('idempresa'))), sprintf('Object sdriving_maquina does not exist (%s).', $request->getParameter('idmaquina'), $request->getParameter('idempresa')));
        $this->form = new SdrivingMaquinaForm($sdriving_maquina);
    }

    public function executeUpdate(sfWebRequest $request) {
        $this->forward404Unless($request->isMethod(sfRequest::POST) || $request->isMethod(sfRequest::PUT));
        $this->forward404Unless($sdriving_maquina = Doctrine_Core::getTable('SdrivingMaquina')->find(array($request->getParameter('idmaquina'), $request->getParameter('idempresa'))), sprintf('Object sdriving_maquina does not exist (%s).', $request->getParameter('idmaquina'), $request->getParameter('idempresa')));
        $this->form = new SdrivingMaquinaForm($sdriving_maquina);
        $this->processForm($request, $this->form);
        $this->setTemplate('edit');
    }

    public function executeDelete(sfWebRequest $request) {
        $this->forward404Unless($sdriving_maquina = Doctrine_Core::getTable('SdrivingMaquina')->find(array($request->getParameter('idmaquina'), $request->getParameter('idempresa'))), sprintf('Object sdriving_maquina does not exist (%s).', $request->getParameter('idmaquina'), $request->getParameter('idempresa')));
        $sdriving_maquina->delete();
        $this->getUser()->setFlash('activeTab', 'maquinas');
        $this->redirect('admin/index');
    }

    protected function processForm(sfWebRequest $request, sfForm $form) {
        $form->bind($request->getParameter($form->getName()), $request->getFiles($form->getName()));
        if ($form->isValid()) {
//            try {
            $sdriving_maquina = $form->save();

            $this->getUser()->setFlash('activeTab', 'maquinas');
            $this->redirect('admin/index');
//            } catch (Exception $e) {
//                $this->getUser()->setFlash('error', 'Los valores no pueden estar duplicados, verifíquelo e inténtelo nuevamente');
//            }
        }
    }

}

编辑2

经过测试,告诉我的是结果:

originalForm: array(5) { ["idmaquina"]=> string(0) "" ["idempresa"]=> string(1) "1" ["_csrf_token"]=> string(32) "54e5e3984c245e60b17abbf32518d95e" ["patente"]=> string(7) "TB58966" ["no_emisor"]=> string(1) "2" }
  

致命错误:在非对象中调用成员函数getValue()   /var/www/html/monitor/apps/frontend/modules/maquina/actions/actions.class.php   在第56行

所以idmaquina永远不会得到值

编辑3:解决方案 我要做的第一件事是修复schema.yml(有关最佳信息,请参阅this post,此处不再重复此解决方案)。然后在SdrivingMaquinaForm.class.php文件中我改变了这个:

protected function doUpdateObject($values) {
    parent::doUpdateObject($values);

    if (isset($this['no_emisor'])) {
        if ($this->isNew()) {
            $sdrivingMaquinaEmisor = new SdrivingMaquinaEmisor();
            $this->getObject()->setSdrivingMaquinaEmisor($sdrivingMaquinaEmisor);
        } else {
            $sdrivingMaquinaEmisor = $this->getObject()->getSdrivingMaquinaEmisor();
        }

        $sdrivingMaquinaEmisor->setIdemisor($this->values['no_emisor']);
        $this->getObject()->getSdrivingMaquinaEmisor()->setIdemisor($this->values['no_emisor']);
    }
}

protected function updateDefaultsFromObject() {
    parent::updateDefaultsFromObject();
    if (isset($this['no_emisor'])) {
        $this->setDefault('no_emisor', $this->getObject()->getSdrivingMaquinaEmisor()->getIdemisor());
    }
} 

当然我还在idempresa方法设置了configure(),如下所示:

$this->widgetSchema['idempresa'] = new sfWidgetFormInputHidden();
$id_empresa = $this->current_user->getSfGuardUserProfile()->getIdempresa();
$this->setDefault('idempresa', $id_empresa);

这就是全部,在修复架构并添加代码后,我可以按照自己的意愿运行

1 个答案:

答案 0 :(得分:1)

我可能错了,但我认为您应该在 configure()函数中添加idmaquina字段的小部件和验证器。

$this->widgetSchema['idmaquina'] = new sfWidgetFormInputHidden();
$this->validatorSchema['idmaquina'] = new sfValidatorChoice(array('choices' => array($this->getObject()->get('idmaquina')), 'empty_value' => $this->getObject()->get('idmaquina'), 'required' => false));

由于您尚未在重载表单中创建它,因此它永远不会将其值保存到表单中,并且当您发送表单时,idmaquina将为null。您可以使用表单字段idmaquina的简单var_dump轻松调试它。

更改表单后,转到命令行,在symfony项目文件夹中,清除symfony缓存:symfony cc

请添加以下代码并检查其值:

doUpdateObject

doUpdateObject($values){
    echo "values: "; var_dump($values); echo "<br />";
    ///...
}

processForm

protected function processForm(sfWebRequest $request, sfForm $form) {
    $originalForm = $request->getParameter($form->getName()), 
    $request->getFiles($form->getName());
    echo "originalForm: "; var_dump($originalForm); echo "<br />";
    echo "idmaquina: " . $originalForm['idmaquina']->getValue(); echo "<br />";
    //...
}

您需要确保在表单中设置并发送idmaquina的值。