CakePHP中的多重关系

CakePHP中的多重关系,cakephp,models,relationships,Cakephp,Models,Relationships,假设(没有更好的例子)我有一个模特儿和另一个模特儿双胞胎(意思是一对双胞胎)。Twins有两个人的外键,比如first_born_id和second_born_id引用两个不同的人(亲自)的id字段。如何在蛋糕中建立关系 我猜Twin会有这样的东西: $belongsTo = array('FirstBorn' => array('className' => 'Person', 'foreignKey'

假设(没有更好的例子)我有一个模特儿和另一个模特儿双胞胎(意思是一对双胞胎)。Twins有两个人的外键,比如first_born_id和second_born_id引用两个不同的人(亲自)的id字段。如何在蛋糕中建立关系

我猜Twin会有这样的东西:

$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'));
但是,当我有一个人,我想知道他的孪生兄弟,我需要检查这两种关系。我想我希望有一种方法能让一个人拥有一个“孪生”关系,它代表了一个人在孪生关系中的两种方式中的任何一种


或者有更好的方法来设置它吗?

为什么要定义这样的双胞胎

双胞胎,第一胎或第二胎是人。把他们和父母联系在一起的是,他们是一个“孩子”,他们的“出生日期”是一样的

那么,你会不会做一些类似于:

$belongsTo = array('FirstBorn' => array('className' => 'Person',
                                        'foreignKey' => 'firstborn_id'),
                   'SecondBorn' => array('className' => 'Person',
                                         'foreignKey' => 'secondborn_id'));
人-> 身份证件 名称 年龄, DOB, 家长ID

父_ID存储在childs记录中,双胞胎是通过比较DOB?的父项下的所有子项来确定的


这会使建立cakePHP关系变得更容易吗?

我同意Twin示例有点混乱。让我假设您有一个
产品
模型(在您的示例中是孪生的),并且它始终有两个
组件
模型连接到它

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'
    )
);
基本上,您应该将您的
hasOne
替换为
hasMany
。每个组件都有许多产品,其中它是第一个组件。同时,它有许多产品,它是第二个组成部分。希望这能说明问题

编辑1:(哦,还有“ProductWithComponentAsComponent”#只是为了解释。根据您的实际型号,您可以保留任何简短的别名。)

编辑2:使用hasOne关系的简单经验法则-仅当您将一个表拆分为多个表时使用它(如用户/配置文件)

编辑3:如果您想要为一个组件提供所有产品,则可以通过两种方式实现

(A) 在hasMany关系中将foreignKey定义为
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) 如果上面的方法不起作用(Cake有时会表现得很奇怪),您还可以使用连接使其服从。在组件模型中创建一个函数,如下所示:

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
                )
            )
        )
    ));
}

啊,我想我的例子选择得不太好。在实际应用中,Person是一种组件,Twin是由其中两个组件(或者实际上可能只有其中一个)组成的产品。所以这两个“人”之间没有别的联系,只是它们一起组成了一对“双胞胎”。啊,我明白了——这个“捆绑”的组件是否只有两条记录?您是否能够发布当前的数据结构?是的,只能有两个组件(它们在产品中具有不同的角色,因此它们也因其角色而有所区别,因此在示例中为“第一个”和“第二个”)。我不能发布实际的代码,但是模型看起来与示例中的完全一样(加上一些不相关的东西)。component数据库表有一个“id”字段,product表有两个外键字段(“component_a_id”和“component_b_id”),都引用了component“id”字段。也许我误解了你的意思,但是component模型代表一个组件的实例(而不是组件的类型),并且一个组件只能是一个产品的一部分(也是一个实例,不是“类”)作为component1或component2。那么关系不应该是hasOne吗?同样,对于您的组件模型(基本上与第一个示例中的我相同,除了hasOne->hasMany),问题仍然是如何访问组件的产品而不必检查这两个关系(我可能不在乎组件是产品的component1还是component2)。如果愿意,您可以用ComponentInstance替换组件。请参阅编辑2关于hasOne:主要在拆分表时使用它。要访问组件的所有产品,请参阅编辑3.:)啊。我不知道您可以将foreignKey设置为false(这在什么地方有记录吗?)。但是它似乎破坏了递归性。当组件的递归设置为2时,我得到一个“未知列:WHERE子句中的Component.id”错误,因为组件不存在于单独的查询中(来自递归性)对于定期声明的foreignKey关系,这些类型的查询以常量形式获取id(例如,“3”而不是“组件”。“id”)。你可以做一些类似方法B的事情,但我曾希望有一种方法可以更好地与CakePHP系统的其余部分集成。是的,正如我提到的,Cake有时会表现得很奇怪!使用可包含的行为而不是递归。除此之外,我想你还可以:)是的,我可以避免Containeable的问题,但我仍然无法(自动地)获得与产品相关的模型,就好像它是一个定期定义的外键关系。也许我可以在组件中使用afterFind做一些事情,但它可能会感觉有点黑客(我必须使用Containable避免自动递归,然后使用afterFind..或其他方法获得它。)谢谢您的帮助!