Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/elixir/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
CakePHP中的自反多对多关系_Php_Cakephp - Fatal编程技术网

CakePHP中的自反多对多关系

CakePHP中的自反多对多关系,php,cakephp,Php,Cakephp,我一直在寻找这个问题的明确答案,但一直无法解决它。我最近一直在使用(并学习)CakePHP,遇到了一个障碍。为了简化我的数据库,假设我们只有两个表: 人员 关系(或人与人) 人与自身有多对多的关系——事实上,两个人之间可以有不止一种关系: persons ------- *person_id* name relationships ------------- *relationship_id* person_1_id person_2_id start_date end_date 现在,如果

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

人员
关系
(或
人与人

人与自身有多对多的关系——事实上,两个人之间可以有不止一种关系:

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

relationships
-------------
*relationship_id*
person_1_id
person_2_id
start_date
end_date
现在,如果我想说Person1(id=1)与Person2结婚,我会在
关系表中有一个条目<代码>人员id
将是
1
,而
人员id
将是两个

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

以下是模型:

类成员扩展了AppModel{
public$hasMany=array(
“关系”=>数组(
'className'=>'Relationship',
'foreignKey'=>'person\u 1\u id'
)
);
}
类关系扩展了AppModel{
public$belongsTo=数组(
“Person1”=>数组(
“className”=>“Person”,
'foreignKey'=>'person\u 1\u id'
),
“Person2”=>数组(
“className”=>“Person”,
'foreignKey'=>'person\u 2\u id'
)
);
}

有什么建议吗?当person\u 1\u id实际上与person\u 2\u id不分离时,复制关系实体在逻辑上是没有意义的。

我认为您有两种选择:

1.复制关系记录 从不同的角度看待它;考虑一个图和一个图的概念。您当前的模式支持有向边离开一个对象(人)到达另一个对象(人)。从您的应用程序的角度来看,一个人不可能在不知情的情况下与另一个人建立关系

如果您选择沿着这条路线走下去,那么数据库中的空间量可以忽略不计,并且实现起来比选项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'
        )
    );
}
然后,根据你的人所处的关系的哪一方,你会为你的关系设置单独的箱子。然后,您必须在所有位置放置额外的逻辑,以便可以将关系容器作为一个同质集合来处理

很抱歉,我帮不上什么忙,但我无法从头开始思考,如何实现一个无向图而不在有向图之上构建它

2013年5月5日更新 要总结注释线程,在
hasMany
关联上设置
finderQuery
,可以屏蔽重复查找与
person_2_id
()关联的需要:


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

感谢您深思熟虑的回答,Sam。这基本上是我一直在考虑的两个选项。我保留的一部分是,我可以不使用ORM轻松地实现这一点-连接将是一个OR键,我正在尝试解决如何在这里应用它。我尝试了hasMany关系的finderQuery,但没有成功。现在,我不回答这个问题,但最终我可能会选择选项1。别担心@AnthonyAziz,我很高兴我能帮你解决一点难题。当你指的是finderQuery时,你的意思是
$this->Model->query(“…”)
?在hasMany关系中,finderQuery应该是一种指定自定义查询的方法-这个想法来自于这篇文章:在玩了一些之后,Sam,我能够让它与finder查询一起工作-问题是我的hasMany关联被命名了“关系”和SQL查询的表别名为“关系”“显然这是个问题?无论如何,我将此标记为一个答案,或者是为了您的有用提示,或者是因为我最终可能会使用具有复制/反向关系的定向设计。再次感谢你的帮助!谢谢@AnthonyAziz我已经在更新答案中总结了我们的讨论,以便对其他人有所帮助。
'Relationship' => array(
    'finderQuery' => 'SELECT Relationship.* FROM relationships AS Relationship WHERE Relationship.person_2_id = {$__cakeID__$} OR Relationship.person_1_id = {$__cakeID__$};'
)