CakePHP中的反复多对多关系 [英] Reflexive many-to-many relationship in CakePHP

查看:89
本文介绍了CakePHP中的反复多对多关系的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I've been searching around for a definitive answer to this issue but have been unable to resolve it. I've recently been working with (and learning) CakePHP and have run across an obstacle. To simplify my database, let's say we simply have two tables:

persons
关系(或 persons_persons

人有多对多并且事实上,两个人可以彼此具有多于一个的关系:

Persons has a many-to-many relationship with itself - and indeed, two people can have more than one relationship with each other:

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

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

,如果我想说Person1(id = 1)结合Person2,我将在关系表中有一个条目。 person_1_id 会是 1 ,而 person_2_id

Now, if I want to say Person1 (id=1) is married to Person2, I would have one entry in the relationships table. person_1_id would be 1, and person_2_id would be two.

我可以在CakePHP中创建此关系,并显示每个Person记录的关系(和人物)列表。但是,它是一个单向关系:对于Person 1,查询只会拉取 Relationship 对象,其中 person_1_id 匹配。如果我要查询Person 2的关系,我必须有第二个相同的行,用 person_1_id person_2_id 已交换。

I can create this relationship in CakePHP, and show the lists of relationships (and persons) per Person record. However, it's a unidirectional relationship: for Person 1, the query will only pull Relationship objects where person_1_id matches. If I want to query the relationships for Person 2, I'd have to have a second identical row, with the person_1_id and person_2_id swapped.

以下是型号:

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

有任何建议吗?

推荐答案

我认为你已经有两个选项:

I think you've got two options:

从不同的角度观察它;请考虑定向未定向图表。您当前的模式支持一个有向边,留下一个对象(Person)并到达另一个对象。从您的应用程序的角度来看,一个人不能与另一个人有关系,而他们不知道。

Look at it from a different perspective; Consider the concept of directed vs. an un-directed graph. Your current schema supports a directed edge leaving one object (Person) and arriving at another. Agreed from your application's perspective, a person can't have a relationship with another, without them knowing.

如果您选择了数据库中的空间量可以忽略不计沿着这条路线行进,实施起来不如选项2那么复杂。请记住,你应该采取措施,确保关系始终保持对称。

The amount of space within the database would be negligible if you did choose to go down this route and would be less complex to implement than option 2. Bare in mind that you should put in place measures to ensure the relationship remains symmetrical at all times.

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

Create another relationship so your model looks like the following:

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

然后您的关系具有单独的仓位,取决于关系的哪一方人存在。然后你必须在每个地方添加额外的逻辑,这样你可以处理关系bin作为一个均匀的集合。

You then have separate bins for your relationships depending on which side of the relationship your person exists. You then have to put extra logic everywhere so that you can handle the relationship bins as one homogeneous collection.

对不起,我不能再有任何帮助,但我不能想到我的头顶,如何实现一个无向的图,而不建立在有向的顶部。

I'm sorry I couldn't be any more helpful but I can't think off the top my head, how to implement an un-directed graph without building it on top of a directed one.

要总结注释线程,请在 hasMany finderQuery c>关联可以隐藏需要重复查找与 person_2_id 文档):

To summarize the comment thread, setting the finderQuery on the hasMany association can mask the need to duplicate the lookup for the association with person_2_id (Documentation):

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

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

This hides the complex retrieval mechanism but storing relationships may require further thought.

这篇关于CakePHP中的反复多对多关系的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆