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