我同意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
)
)
)
));
}
也許我誤解了你,但組件模型代表組件的一個實例(不是一種組件類型),組件只能作爲一個產品(也是一個實例,而不是一個「類」)的一部分,作爲組件1或組件2。那麼關係應該不是一個? 此外,隨着你的組件模型(基本上與第一個例子中的相同,除了hasOne-> hasMany),問題仍然是如何訪問組件的Product而不必檢查兩個關係(我可能不在乎組件是產品的組件1或組件2)。 – zephyr 2011-01-05 20:58:04
如果您願意,您可以用ComponentInstance替換Component。關於hasOne,請參閱編輯2:主要在分割表格時使用它。要訪問組件的所有產品,請參閱編輯3. :) – RabidFire 2011-01-06 02:56:21
啊。我不知道你可以將ForeignKey設置爲false(這是否記錄在某處?)。但它似乎打破了遞歸。對於組件,遞歸設置爲2時,我得到一個「未知列:WHERE子句中的Component.id」錯誤,因爲組件在產品上的單獨查詢(來自遞歸)中不存在。對於定期聲明的foreignKey關係,這些類型的查詢將id作爲常量(例如「(3)」而不是「Component」。「id」)。人們可以做類似於你的方法B的事情,但我希望有一種方法可以與CakePHP系統的其他部分更好地集成。 – zephyr 2011-01-06 11:48:52