Doctrine_Record_Exception "无法调用 Doctrine_Core::set()";同时尝试保存表单数据 [英] Doctrine_Record_Exception "Couldn't call Doctrine_Core::set()" while try to save form data

查看:21
本文介绍了Doctrine_Record_Exception "无法调用 Doctrine_Core::set()";同时尝试保存表单数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我遇到了这个问题,但我找不到问题所在.我正在尝试在执行表单保存方法之前更新对象,我按照以下步骤操作(我写了整个类以防万一):

class SdrivingMaquinaForm 扩展 BaseSdrivingMaquinaForm {受保护的 $current_user;公共功能配置(){$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();}受保护的函数 doUpdateObject($values) {parent::doUpdateObject($values);如果 (isset($this['no_emisor'])) {如果 ($this->isNew()) {$sdrivingMaquinaEmisor = new SdrivingMaquinaEmisor();$this->getObject()->setSdrivingMaquinaEmisor($sdrivingMaquinaEmisor);} 别的 {$sdrivingMaquinaEmisor = $this->getObject()->getSdrivingMaquinaEmisor();}$sdrivingMaquinaEmisor->setIdemisor($this->values['no_emisor']);}}}

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

SdrivingMaquina:充当:时间戳:~列:idmaquina: { type: integer(8), autoincrement: true, notnull: true, primary: true }idempresa: { type: integer(4), notnull: true }专利:{ 类型:字符串(12),notnull:真}关系:Empresa: { local: idempresa, class: SdrivingEmpresa, type: one, foreignType: one, foreignAlias: MaquinaEmpresa, onDelete: CASCADE, onUpdate: CASCADE }SdrivingMaquinaEmisor:充当:时间戳:~列:idmaquinaemisor: { type: integer(8), primary: true, autoincrement: true }idmaquina: { type: integer(8), notnull: true }idemisor: { type: integer(8), notnull: true }关系: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 后是否应该更改逻辑并更新关系值?在那种情况下,我如何获得创建的最新 maquinaid?

编辑模板:_form.php

<?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() 并打印 '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 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 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></表单><?php if ($sf_user->hasFlash('error')): ?><div class="alert alert-error"><h4>错误!</h4><?php echo $sf_user->getFlash('error') ?>

<?php endif;?>

<脚本>$(函数(){$('#cancel-btn').click(function() {历史.go(-1);$('#myTab a[href="#<?php echo $sf_user->getFlash('activeTab', 'usuarios'); ?>"]').tab('show');});});

动作类:action.class.php

class maquinaActions 扩展 sfActions {公共函数执行索引(sfWebRequest $request){$this->sdriving_maquinas = Doctrine_Core::getTable('SdrivingMaquina')->createQuery('a')->execute();}公共函数 executeNew(sfWebRequest $request) {$this->getUser()->setFlash('activeTab', 'maquinas');$this->form = new SdrivingMaquinaForm();}公共函数执行创建(sfWebRequest $request){$this->forward404Unless($request->isMethod(sfRequest::POST));$this->form = new SdrivingMaquinaForm();$this->processForm($request, $this->form);$this->setTemplate('new');}公共函数执行编辑(sfWebRequest $request){$this->forward404Unless($sdriving_maquina = Doctrine_Core::getTable('SdrivingMaquina')->find(array($request->getParameter('idmaquina'), $request->getParameter('idempresa'))), sprintf('对象 sdriving_maquina 不存在 (%s).', $request->getParameter('idmaquina'), $request->getParameter('idempresa')));$this->form = new SdrivingMaquinaForm($sdriving_maquina);}公共函数执行更新(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('对象 sdriving_maquina 不存在 (%s).', $request->getParameter('idmaquina'), $request->getParameter('idempresa')));$this->form = new SdrivingMaquinaForm($sdriving_maquina);$this->processForm($request, $this->form);$this->setTemplate('edit');}公共函数执行删除(sfWebRequest $request){$this->forward404Unless($sdriving_maquina = Doctrine_Core::getTable('SdrivingMaquina')->find(array($request->getParameter('idmaquina'), $request->getParameter('idempresa'))), sprintf('对象 sdriving_maquina 不存在 (%s).', $request->getParameter('idmaquina'), $request->getParameter('idempresa')));$sdriving_maquina->delete();$this->getUser()->setFlash('activeTab', 'maquinas');$this->redirect('admin/index');}受保护的函数 processForm(sfWebRequest $request, sfForm $form) {$form->bind($request->getParameter($form->getName()), $request->getFiles($form->getName()));如果 ($form->isValid()) {//           尝试 {$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"]=>字符串(32)54e5e3984c245e60b17abbf32518d95e"[专利"]=>字符串(7)TB58966"[no_emisor"]=>字符串(1)2"}

<块引用>

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

所以 idmaquina 永远不会得到值

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

受保护的函数 doUpdateObject($values) {parent::doUpdateObject($values);如果 (isset($this['no_emisor'])) {如果 ($this->isNew()) {$sdrivingMaquinaEmisor = new SdrivingMaquinaEmisor();$this->getObject()->setSdrivingMaquinaEmisor($sdrivingMaquinaEmisor);} 别的 {$sdrivingMaquinaEmisor = $this->getObject()->getSdrivingMaquinaEmisor();}$sdrivingMaquinaEmisor->setIdemisor($this->values['no_emisor']);$this->getObject()->getSdrivingMaquinaEmisor()->setIdemisor($this->values['no_emisor']);}}受保护的函数 updateDefaultsFromObject() {parent::updateDefaultsFromObject();如果 (isset($this['no_emisor'])) {$this->setDefault('no_emisor', $this->getObject()->getSdrivingMaquinaEmisor()->getIemisor());}}

当然我也在 configure() 方法中设置了 idempresa 如下:

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

就是这样,在修复架构并添加代码之后,一切都按我想要的方式工作

解决方案

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

$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 将为空.您可以使用表单字段 idmaquina 的简单 var_dump 轻松调试它.

更改表单后,转到命令行并在您的 symfony 项目文件夹中,使用以下命令清除 symfony 缓存:symfony cc

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

doUpdateObject中:

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

processForm中:

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

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

I'm having this issue and I can't find what is wrong. I'm trying to update object before execute the form save method and I do as follow (I wrote the whole class just in case):

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']);
        }
    }
}

This is the schema.yml related to that form:

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 }

As you may notice none relation is many to many. When I send the form I get this error:

Couldn't call Doctrine_Core::set(), second argument should be an instance of Doctrine_Collection when setting one-to-many references.

And I couldn't find where the error is so any help will be appreciated. Also I notice this in the stack trace:

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

Why idmaquina is null? There should go the value of the maquina I'm creating in the same moment. Should I change my logic and update the relation values after save the maquina? In that case how I get the id of the newest maquina created?

EDIT template: _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: 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');
//            }
        }
    }

}

EDIT 2

After test what been told to me here are the results:

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

Fatal error: Call to a member function getValue() on a non-object in /var/www/html/monitor/apps/frontend/modules/maquina/actions/actions.class.php on line 56

So idmaquina never gets a value

EDIT 3: solution The first thing I do was fix the schema.yml (see this post for best information and not repeat the solution here). Then in SdrivingMaquinaForm.class.php file I change this:

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());
    }
} 

of course also I set idempresa at configure() method as follows:

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

That was all, after fix the schema and add the code things works as I want

解决方案

I may be wrong but I think you should add the widget and validator for idmaquina field in your form configure() function.

$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));

Since you havent created it in your overloaded form, its never saving its value into the form, and when you send the form, idmaquina will be null. You can easily debug it with a simple var_dump of the form field idmaquina.

After changing your form, go to command line and in your symfony project folder, clear symfony cache with: symfony cc

Please add the following code and check for its value:

In doUpdateObject:

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

In 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 />";
    //...
}

You need to make sure that you are setting and sending the value of idmaquina in your form.

这篇关于Doctrine_Record_Exception "无法调用 Doctrine_Core::set()";同时尝试保存表单数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
其他开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆