2011-01-05 103 views
0

假設(缺乏更好的例子)我有一個模型Person和另一個模型Twin(意思是一對雙胞胎)。雙胞胎擁有兩個Person外鍵,例如first_born_id和second_born_id引用兩個不同人的id字段(in Person)。我如何在蛋糕中建立關係?CakePHP中的多重關係

我猜雙牀會碰到這樣的:

$belongsTo = array('FirstBorn' => array('className' => 'Person', 
             'foreignKey' => 'firstborn_id'), 
        'SecondBorn' => array('className' => 'Person', 
             'foreignKey' => 'secondborn_id')); 

但我應該怎麼設置的人嗎?我能做到這一點,如:

$hasOne = array('TwinAsFirstborn' => array('className' => 'Twin', 
              'foreignKey' => 'firstborn_id'), 
       'TwinAsSecondborn' => array('className' => 'Twin', 
              'foreignKey' => 'secondborn_id')); 

但後來當我有一個人,我想知道它的孿生兄弟,我需要檢查這兩個關係。我想我希望有一種方法可以在Person中獲得「雙胞胎」關係,這表示Person可以處於雙胞胎關係的兩種方式。

或者有更好的方法來設置它嗎?

回答

1

我同意Twin的例子有點混亂。讓我假設你有一個Product模型(在你的例子中是Twin),它總是有2個連接到它的Component模型。

components: id - name 
products: id - component1_id - component2_id 

我會成立產品如下:

var $belongsTo = array(
    'Component1' => array(
     'className' => 'Component', 
     'foreignKey' => 'component1_id' 
    ), 
    'Component2' => array(
     'className' => 'Component', 
     'foreignKey' => 'component2_id' 
    ) 
); 

和組件爲:

var $hasMany = array(
    'ProductWithComponentAsComponent1' => array(
     'className' => 'Product', 
     'foreignKey' => 'component1_id' 
    ), 
    'ProductWithComponentAsComponent2' => array(
     'className' => 'Product', 
     'foreignKey' => 'component2_id' 
    ) 
); 

基本上,你應該hasMany取代你hasOne。每個組件都有許多產品,它是第一個組件。同時,它有許多產品,它是第二個組件。希望能夠說清楚。

編輯1:(呵呵,「ProductWithComponentAsComponent#」只是爲了解釋的目的,你可以根據你的實際模型保留你喜歡的任何簡短,甜美的別名。)

編輯2:根據經驗,使用hasOne關係規則很簡單 - 使用它,只有當你將單個表分成許多(如用戶/個人資料)

編輯3:如果你想所有產品的組件,那麼你可以通過兩種方式做到這一點。 (A)在您的hasMany關係中將外鍵定義爲false

var $hasMany = array(
    'Product' => array(
     'className' => 'Product', 
     'foreignKey' => false, 
     'conditions' => array(
      'or' => array(
       "Product.component1_id = Component.id", 
       "Product.component2_id = Component.id" 
      ) 
     ) 
    ) 
); 

(B)如果上面的方法不起作用(蛋糕怪異的行爲,然後現在),你也可以使用一個連接,使之服從。在組件模型中創建一個函數,如下所示:

function fetchProducts($id) { 
    if (!$id) { 
     return null; 
    } 
    return $this->Product->find('all', array(
     'fields' => array('Product.*'), 
     'joins' => array(
      array(
       'table' => 'components', 
       'alias' => 'Component', 
       'foreignKey' => false, 
       'type' => 'inner', 
       'conditions' => array(
        'or' => array(
         "Product.component1_id = Component.id", 
         "Product.component2_id = Component.id" 
        ), 
        'Component.id' => $id 
       ) 
      ) 
     ) 
    )); 
} 
+0

也許我誤解了你,但組件模型代表組件的一個實例(不是一種組件類型),組件只能作爲一個產品(也是一個實例,而不是一個「類」)的一部分,作爲組件1或組件2。那麼關係應該不是一個? 此外,隨着你的組件模型(基本上與第一個例子中的相同,除了hasOne-> hasMany),問題仍然是如何訪問組件的Product而不必檢查兩個關係(我可能不在乎組件是產品的組件1或組件2)。 – zephyr 2011-01-05 20:58:04

+0

如果您願意,您可以用ComponentInstance替換Component。關於hasOne,請參閱編輯2:主要在分割表格時使用它。要訪問組件的所有產品,請參閱編輯3. :) – RabidFire 2011-01-06 02:56:21

+0

啊。我不知道你可以將ForeignKey設置爲false(這是否記錄在某處?)。但它似乎打破了遞歸。對於組件,遞歸設置爲2時,我得到一個「未知列:WHERE子句中的Component.id」錯誤,因爲組件在產品上的單獨查詢(來自遞歸)中不存在。對於定期聲明的foreignKey關係,這些類型的查詢將id作爲常量(例如「(3)」而不是「Component」。「id」)。人們可以做類似於你的方法B的事情,但我希望有一種方法可以與CakePHP系統的其他部分更好地集成。 – zephyr 2011-01-06 11:48:52

0

爲什麼要定義一個這樣的雙胞胎?

雙胞胎,第一或第二齣生是一個人。將他們與父母關聯的事實是他們是「孩子」,他們的「DOB」是相同的。

所以,你會不會做這樣的事情:

人 - > ID, 名稱, 年齡, DOB, PARENT_ID

的PARENT_ID存入孩子的記錄,而雙是通過比較父母下的所有孩子來確定DOB?

這是否使它更容易設置您的CakePHP關係?

+0

啊,好吧,我想我的例子並沒有太好的選擇。在實際應用中,Person是一種組件,Twin是由兩個組件組成的產品(或者實際上可能只有其中一個)。所以這兩個「人」沒有別的聯繫,只是他們組成了一對「雙胞胎」。 – zephyr 2011-01-05 13:30:44

+0

Ahhh我看到了 - 這個「捆綁」組件只有2條記錄嗎? 你能發佈你當前的數據結構嗎? – diagonalbatman 2011-01-05 13:32:31

+0

是的,只能有兩個組件(它們在產品中有不同的角色,所以它們也因其作用而有所區別,因此在本例中爲「頭生」和「次胎」)。 我無法發佈實際的代碼,但模型看起來完全像這個例子(加上一些不相關的東西)。組件數據庫表具有「id」字段,產品表具有兩個引用組件「id」字段的外鍵字段(「component_a_id」和「component_b_id」)。 – zephyr 2011-01-05 13:46:48