在CakePHP中反思多对多的关系

时间:2013-05-04 03:53:28

标签: php cakephp

我一直在寻找这个问题的明确答案,但一直无法解决。我最近一直在和(和学习)CakePHP一起工作,遇到了障碍。为了简化我的数据库,假设我们只有两个表:

persons relationships(或persons_persons

人与自己有多对多的关系 - 事实上,两个人之间可以有多个关系:

persons
-------
*person_id*
name

relationships
-------------
*relationship_id*
person_1_id
person_2_id
start_date
end_date

现在,如果我想说Person1(id = 1)与Person2结婚,我会在relationships表中有一个条目。 person_1_id1person_2_id为2。

我可以在CakePHP中创建这种关系,并显示每个人员记录的关系(和人员)列表。但是,它是一种单向关系:对于Person 1,查询只会提取Relationship匹配的person_1_id个对象。如果我想查询Person 2的关系,我必须有第二行,person_1_idperson_2_id交换。

以下是模型:

class Member extends AppModel {
    public $hasMany = array(
        'Relationships' => array(
            'className' => 'Relationship',
            'foreignKey' => 'person_1_id'
        )
    );
}

class Relationship extends AppModel {
    public $belongsTo = array(
        'Person1' => array(
            'className' => 'Person',
            'foreignKey' => 'person_1_id'
        ),
        'Person2' => array(
            'className' => 'Person',
            'foreignKey' => 'person_2_id'
        )
    );
}

有什么建议吗?当person_1_id实际上与person_2_id没有分开时,复制关系实体没有逻辑意义。

1 个答案:

答案 0 :(得分:3)

我认为你有两个选择:

1。复制关系记录

从不同的角度看待它;考虑directedun-directed图的概念。您当前的架构支持一个有向边,留下一个对象(Person)并到达另一个对象。从你的申请的角度来看,一个人在没有他们知情的情况下就不能与他人建立关系。

如果您确实选择沿着这条路线走下去并且实施起来比选项2复杂,那么数据库中的空间量可以忽略不计。请注意,您应该采取措施确保关系保持对称。所有时间。

2。处理应用程序中的关系不对称

创建另一种关系,使您的模型如下所示:

class Member extends AppModel {
    public $hasMany = array(
        'RelationshipsA' => array(
            'className' => 'Relationship',
            'foreignKey' => 'person_1_id'
        ),
        'RelationshipsB' => array(
            'className' => 'Relationship',
            'foreignKey' => 'person_2_id'
        )
    );
}

然后根据您所在人的关系的哪一方,为您的关系设置单独的箱子。然后,您必须在任何地方放置额外的逻辑,以便您可以将关系箱作为一个同类集合来处理。

对不起,我不能再有所帮助了,但我无法想到最好的问题,如何在没有指导图的情况下实现无指导图。

更新05/05/13

要总结评论主题,在finderQuery关联上设置hasMany可能会掩盖重复与person_2_idDocumentation)关联的查找的需要:< / p>

'Relationship' => array(
    'finderQuery' => 'SELECT Relationship.* FROM relationships AS Relationship WHERE Relationship.person_2_id = {$__cakeID__$} OR Relationship.person_1_id = {$__cakeID__$};'
)

这隐藏了复杂的检索机制,但存储关系可能需要进一步考虑。