2013-06-21 2 views
0

Я это schema.yml:Получить идентификатор из последних сохраненных данных формы

SdrivingMaquina: 
    connection: doctrine 
    tableName: sdriving_maquina 
    actAs: [Timestampable] 
    columns: 
    idmaquina: { type: integer(8), fixed: false, unsigned: false, primary: true, autoincrement: true } 
    idempresa: { type: integer(4), fixed: false, unsigned: true, primary: true, autoincrement: false } 
    patente: { type: string(12), fixed: false, unsigned: false, primary: false, notnull: true, autoincrement: false } 
    relations: 
    Empresa: { local: idempresa, class: SdrivingEmpresa, type: one, foreignType: one, foreignAlias: MaquinaEmpresa, onDelete: CASCADE, onUpdate: CASCADE } 
SdrivingMaquinaEmisor: 
    connection: doctrine 
    tableName: sdriving_maquina_emisor 
    actAs: [Timestampable] 
    columns: 
    idmaquinaemisor: { type: integer(8), fixed: false, unsigned: false, primary: true, autoincrement: true } 
    idmaquina: { type: integer(8), fixed: false, unsigned: false, primary: true, autoincrement: false } 
    idemisor: { type: integer(8), fixed: false, unsigned: false, primary: true, autoincrement: false } 
    relations: 
    SdrivingEmisor: { onDelete: CASCADE, local: idemisor, foreign: idemisor, type: one } 
    SdrivingMaquina: { onDelete: CASCADE, local: idmaquina, foreign: idmaquina, type: one } 

И это configure() метод для формы, связанные:

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

Пытаюсь после сохраните основной файл maquina, затем сохраните данные для связи SdrivingMaquinaEmisor(), но не знаете и не нашли (после некоторых исследований Google и Stackoverflow) правильный способ получить последний идентификатор объекта SdrivingMaquina.

Это то, что я делаю в моем save() метод (в той же форме):

public function save($con = null) { 
    $new_machine = parent::save($con); 

    $relation = new SdrivingMaquinaEmisor(); 
    $relation->setIdmaquina($new_machine->getIdmaquina()); 
    $relation->setIdemisor($this->values['no_emisor']); 
    $relation->save(); 

    return $new_machine; 
} 

Но setIdmaquina() никогда не получает значение, так это разбивает мое приложение и вызвать ошибку CONSTRAINT, может любой точке меня в правильном направлении?

ответ

1

Вам не обязательно это делать, идентификатор не нужен. Если форма верна и требуемые поля (idempresa) находятся в форме, то отношения будут автоматически сохраняться.

Это не полный ответ (это зависит от многих вещей) к вашему вопросу, но некоторые советы, которые я могу вам дать (надеюсь, вы не против).

Давайте попробуем упростить некоторые вещи:

SdrivingMaquina: 
    actAs: 
    Timestampable: ~ 
    columns: 
    empresa_id: { type: integer(4), unsigned: true, primary: true } 
    patente: { type: string(12), notnull: true } 
    relations: 
    Empresa: { class: SdrivingEmpresa, type: one, foreignType: one, foreignAlias: MaquinaEmpresa, onDelete: CASCADE, onUpdate: CASCADE } 
SdrivingMaquinaEmisor: 
    actAs: 
    Timestampable: ~ 
    columns: 
    maquina_id: { type: integer, notnull: true } 
    emisor_id: { type: integer, notnull: true } 
    relations: 
    SdrivingEmisor: { onDelete: CASCADE, local: emisor_id, type: one } 
    SdrivingMaquina: { onDelete: CASCADE, local: maquina_id, type: one } 

Первичные ключи (как idmaquina) не требуется объявлять явно ... первичный ключ будет добавлен автоматически, и для простоты это будет (и должно быть) с именем id. Doctrine не очень хорошо справляется с составными ключами, поэтому вы должны использовать только одно поле. Если вы хотите обеспечить уникальность, добавьте unique index.

Вы должны указать внешние ключи, такие как empresa_id, а не idempresa, потому что это упростит некоторые вещи.

А в форме (я не знаю, что это форма принадлежит к какой таблице):

/** @var sfDoctrineGuardUser */ 
protected $user; 

public function configure() 
{ 
    // user comes as an option e.g. in an action new SomeForm(null, array('user' => $this->getUser())); 
    $this->user = $this->getOption('user'); 
    if ($this->user instanceof sfDoctrineGuard) 
    { 
     throw new InvalidArgumentException('A sfDoctrineGuard object is required as "user" option in '.__METHOD__); 
    } 

    // use useFields instead of unset 
    $this->useFields(array(
     'empersa_id', 
     'no_emisor', 
     // ... 
    )); 

    // this should be done automatically by symfony in the base class 
    //$this->widgetSchema['idempresa'] = new sfWidgetFormInputHidden(); 
    //$id_empresa = $this->current_user->getSfGuardUserProfile()->getIdempresa(); 
    //$this->setDefault('idempresa', $id_empresa); 

    // do not recreate widgets if not needed (I don't know if no_emisor is in the schema or not), just modify them 
    $this->getWidget('no_emisor')->setOption('table_method', 'fillChoice'); 
    $this->getWidget('no_emisor')->setOption('add_empty', 'Seleccione un Emisor'); 
} 

Если схема является правильным и ссылочное поле как empresa_id в виде Symfony создаст отборное виджет для него, и выбранное значение будет сохранено автоматически. Если вы не хотите, чтобы виджет в форме, вы не должны его вводить (или не устанавливать) и установить значение поля empresa_id в коде. Вы должны переопределить doUpdateObject метод:

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

    // thats it... link objects together and doctrine will figure out the id 
    $this->getObject()->setEmpresa($this->user); 
} 

Вы должны следовать конвенции и лучшие практики (их получить из документации) в целом. Не только потому, что ваш код будет более читабельным и понятным для других людей, но это сделает вашу жизнь намного проще. Я знаю, что для изучения сложных вещей, таких как symfony, требуется много времени, но вы должны прочитать всю документацию (для symfony и доктрины), а затем прочитать сам код symfony, чтобы узнать, как он работает под капотом. Используйте структуру, чтобы упростить вашу работу, чтобы не усложнять ее.

UPDATE:

Это, как вы можете связать объекты вместе перед сохранением (используйте это или что-то вроде этого вместо вашего save метода):

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

большое спасибо за ваш ответ, помочь много. Теперь позвольте мне сказать, что было сделано, как вы видите. Во-первых, я не единственный, кто стоит за этим проектом, другие тоже работают и не уважают хорошие практики, а также не знаю, хорошо ли они знакомы с Symfony, чтобы упростить задачу, например, часть схемы. Они создают BD, а затем я жестко выполнил задачу 'doctrine: build-schema', и поэтому причина в том, что схема не в порядке. С другой стороны, класс (форма и сохранение) принадлежит 'SdrivingMaquina'. – Reynier

+0

К сожалению, я не могу изменить БД в этот момент, чтобы я мог сделать то же самое, что и я. Я пытаюсь сделать все возможное :-(Для методов 'actions.class.php' я использую задачу' doctrine: generate-module', поэтому он создает основную часть CRUD, мне просто нужно добавить поддержку для отношения и да, настроить некоторые формы, потому что, например, в этом я не получил отношения «Emisores», и мне нужно было построить отношение, каковы ваши предложения, с учетом того, что я сказал раньше? – Reynier

+0

@Reynier Я добавил пример на основе схемы ... но я не знаю, будет ли это работать или нет. – 1ed