2011-01-05 104 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