2013-06-21 34 views
0

我有這樣的schema.yml:獲取最新保存的表單數據的ID

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()的數據,但不知道和沒有找到(經過一些谷歌和Stackoverflow研究)正確的方式來獲取最新的ID爲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()所以它打破了我的申請,並導致約束錯誤從來沒有得到一個數值,可以任意點我在正確的方向?

回答

1

你不必這樣做,id是不需要的。如果表格是正確的並且必填字段(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。學說不擅長處理複合鍵,所以你應該只使用一個字段。如果你想確保唯一性,請添加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和doctrine),然後閱讀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

不幸的是,我現在不能更改DB,所以我應該可以使用我所做的來做同樣的事情。我試圖做的最好:-(。對於'actions.class.php'的方法,我使用任務'doctrine:generate-module',因此它創建了基本的CRUD部分,我只需要添加對關係和是的,調整一些形式,因爲例如在這我沒有得到'Emisores'關係,我需要建立關係,你有什麼建議,然後考慮到我之前說過的嗎? – Reynier

+0

@Reynier我加了一個例如基於模式......但我不知道它是否會工作 – 1ed