2011-03-09 22 views
-1

我正在處理涉及3個不同對象的用戶註冊表單,用戶,成員配置文件和成員組織。我試圖將所有這些嵌入到單個註冊表單中,例如用戶>成員>學校。對於典型的sfDoctrineForm::embedRealtion程序,這個基本的實現工作很好。sfDoctrineForm - 如何檢查嵌入式表單中的對象是否存在並將其與新的父對象關聯而不是創建新對象?

問題是組織在其member_number上有一個唯一的索引,唯一提供的值不會在數據庫中,這時用戶是第一個從他們的組織註冊的人。所以在這種情況下,我們將得到一個vlaidation錯誤(如果我們關閉驗證,則會出現關鍵約束違規)。

我想要發生的是,我檢查是否存在與數據庫中相同的member_number MemberOrganization(無論是在前/後驗證程序中,還是在updateObject中或適當的地方)。如果它的成員編號已經存在,那麼我想將新的MemberProfile關聯到這個現有的組織,而不是將它鏈接到提交的新組織,並拋出該組織的所有新值。

伊夫試圖修改通過驗證的組織形式的對象,但這總是導致organization_id約束衝突從配置文件來:

$object = $this->getObject(); 
$table = $object->getTable(); 
$existing = $table->findOneByMemberNumber($values['member_number']); 
if($existing) 
{ 
    $members = clone $object->Members; 
    $object->assignIdentifier($existing->identifier()); 
    $object->fromArray($existing->toArray(false), false); 

    foreach($members as $member) 
    { 
    $member->link($object); 
    } 

    $values = $object->toArray(false); // return only the direct values 
} 

return $values; 

架構看起來是這樣的:

User: 
    columns: 
    username: {type: string(100)} 
    email: {type: string(255), unique: true} 

MemberProfile: 
    columns: 
    # some none authentication related user details 
    organization_id: {type: integer, notull: true} 
    user_id: {type: integer, notnull: true} 
    relations: 
    User: 
     local: user_id 
     type: one 
     foreign: id 
     foreignType: one 
    MemberOrganization: 
     local: orgainization_id 
     type: one 
     foreign: id 
     foreignType: many 
     foreignAlias: Members 

MemberOrganization: 
    columns: 
    membership_number: {type: string(255), unique: true} 
    # other organization data 
+0

看來,在這種情況下,登記表仍試圖保存嵌入的形式,其導致是一種獨特約束錯誤。你有沒有嘗試取消設置相應的對象? – Dziamid

回答

0

所以我最終做的是在頂層窗體(用戶的窗體)上重寫bind。在這種方法中,我檢查是否存在Orgainization,如果存在,我將它附加到Member Profile對象,然後重新嵌入所有子表單。

理想情況下,我會在成員窗體中實際執行此操作,但由於值只能綁定在頂層窗體中,然後只能級聯錯誤模式進行驗證,所以這似乎是不可行的。似乎需要完全重新嵌入才能使對象關聯正確。

一些示例代碼(以下發出查詢之前,對構件數目一些消毒代碼):

public function linkOrganizationIfExists(array $orgValues) 
    { 
    $defaultOrg = $this->embeddedForms['member_profile']->embeddedForms['organization']->getObject(); 
    $table = $defaultOrg->getTable(); 

    if(isset($orgValues['member_number']) 
     && ($existingOrg = $table->findOneByMemberNumber($orgValues['member_number']))) 
    { 
     $user = $this->getObject(); 
     $profile = $user->getMemberProfile(); 
     $profile->Organization = $existingOrg; 

     // prepare the current values from the db to return 
     $orgValues = array_merge($orgValues, array_intersect_key($existingOrg->toArray(false), $orgValues)); 

     $this->embedRelation('MemberProfile as member_profile', 'MemberProfileRegisttrationForm'); 
    } 

    return $orgValues; 
    } 

    public function bind(array $taintedValues = null, array $taintedFiles = null) 
    { 
    if(isset($taintedValues['member_profile']['organization'])) 
    { 
     $taintedValues['member_profile']['organization'] = $this->linkOrganizationIfExists($taintedValues['member_profile']['organization']); 
    } 

    parent::bind($taintedValues, $taintedFiles); 
    } 
相關問題