HABTM与自己需要2x的行在连接表中? [英] HABTM with self requires 2x the rows in join table?
问题描述
我尝试使用 Nodes
作为主要模型来构建CMS。每个节点
belongsTo
a NodeType
$ c> Node 可以与任何/每其他节点
相关。
- 认为这叫HABTM:
//节点模型
public $ hasAndBelongsToMany = array(
' AssociatedNode'=> array(
'className'=>'Node',
'foreignKey'=>'node_id',
'associationForeignKey'=>'associated_node_id',
'joinTable'=>'node_associations'
)
);
问题是,它似乎唯一的方式是,如果我有两个行的每个关联
节点
。- ER(id = 1)
- George Clooney(id = 2)
描述这两个节点之间的关系的连接表中的一行:
- 'node_id'= 1
- 'associated_node_id'= 2
我查询电视节目并包含它的Actor节点:
$ nodes = $ this-> Node-& all',array(
'conditions'=> array(
'Node.node_type_id'=>'645'// tv显示
),
' > array(
'AssociatedNode'=> array(
'conditions'=&array; array(
'AssociatedNode.node_type_id'=>'239'// actors
),
)
)
));
这样工作,我得到ER - > George Clooney。
但是 - 如果我想拉所有乔治·克鲁尼所有的节目呢?
$ nodes = $ this-> Node-> find('all',array(
'conditions'=> array(
'Node.node_type_id'=>'239'// actors
),
'contains'=> array(
'AssociatedNode'=> array(
'conditions'=&array; array(
'AssociatedNode.node_type_id'=& '645'//电视显示
),
)
)
));
这不工作,因为它正在寻找乔治·克鲁尼的ID在node_id
我想到的唯一解决方案是为每一行保留两行协会。但这似乎过分。但是,然后我必须提出一些自定义的东西,确保保持每个副本同步w /其他每次关联保存或删除...等 - 这似乎是一个大罐的蠕虫。 / p>
有没有我遗漏的东西?
做一个自定义查询,但是为了保持标准的Cake函数,我可以想到的一件事是声明节点之间的两个关系:
public $ hasAndBelongsToMany = array(
'AssociatedNode1'=> array(
'className'=>'Node',
'foreignKey'=>'node_id' ,
'associationForeignKey'=>'associated_node_id',
'joinTable'=>'node_associations'
),
'AssociatedNode2'=& 'className'=>'Node',
'foreignKey'=>'associated_node_id',
'associationForeignKey'=>'node_id',
'joinTable'=>'node_associations '
)
);
,然后可以在afterFind回调中合并这两个数组。
function afterFind($ results)
{
foreach($ results as& $ result)
{
if ($($ result ['AssociatedNode1'])|| isset($ result ['AssociatedNode2']))
{
$ associated_nodes = array
if(isset($ result ['AssociatedNode1']))
{
foreach($ result ['AssociatedNode1'] as $ associated_node)
{
$ associated_nodes [] = $ associated_node;
}
}
if(isset($ result ['AssociatedNode2']))
{
foreach($ result ['AssociatedNode2'] as $ associated_node)
{
$ associated_nodes [] = $ associated_node;
}
}
$ result ['AssociatedNode'] = $ associated_nodes;
}
}
unset($ result);
return $ results;
}
但这会迫使您在调用中声明AssociatedNode1和AssociatedNode2 ();
I'm trying to build a CMS with Nodes
as the main model. Each Node
belongsTo
a NodeType
, and every Node
can be related to any/every other Node
.
So - thought this called for HABTM:
//Node model
public $hasAndBelongsToMany = array(
'AssociatedNode' => array(
'className' => 'Node',
'foreignKey' => 'node_id',
'associationForeignKey' => 'associated_node_id',
'joinTable' => 'node_associations'
)
);
The problem is, it seems like the only way it works is if I have TWO rows for each association.
Example with just one association row:
Nodes
- ER (id=1)
- George Clooney (id=2)
A single row in the join-table describing the relationship between those two nodes:
- 'node_id' = 1
- 'associated_node_id' = 2
Now - If I query for TV Shows and Contain it's Actor nodes:
$nodes = $this->Node->find('all', array(
'conditions' => array(
'Node.node_type_id' => '645' //tv shows
),
'contain' => array(
'AssociatedNode' => array(
'conditions' => array(
'AssociatedNode.node_type_id' => '239' //actors
),
)
)
));
This works, and I get ER -> George Clooney.
But - what if I want to pull all shows that George Clooney is in?
$nodes = $this->Node->find('all', array(
'conditions' => array(
'Node.node_type_id' => '239' //actors
),
'contain' => array(
'AssociatedNode' => array(
'conditions' => array(
'AssociatedNode.node_type_id' => '645' //tv shows
),
)
)
));
This doesn't work because it's looking for George Clooney's ID to be in the 'node_id' field, and ER's ID to be in the 'associated_node_id' field - when in reality they're reversed.
The only solution I've thought of is to keep two rows for EVERY association. But this seems overkill. But then I have to come up with some kind of custom something that makes sure to keep each duplicate in sync w/ the other every time an association is saved or deleted...etc - and this seems like a large can of worms.
Is there something I'm missing?
You could probably do it with a custom query, but to keep with standard Cake functions, one thing I can think of would be to declare two relationships between the Nodes:
public $hasAndBelongsToMany = array(
'AssociatedNode1' => array(
'className' => 'Node',
'foreignKey' => 'node_id',
'associationForeignKey' => 'associated_node_id',
'joinTable' => 'node_associations'
),
'AssociatedNode2' => array(
'className' => 'Node',
'foreignKey' => 'associated_node_id',
'associationForeignKey' => 'node_id',
'joinTable' => 'node_associations'
)
);
and then you could merge both arrays in an afterFind callback.
function afterFind($results)
{
foreach($results as &$result)
{
if(isset($result['AssociatedNode1']) || isset($result['AssociatedNode2']))
{
$associated_nodes = array();
if(isset($result['AssociatedNode1']))
{
foreach($result['AssociatedNode1'] as $associated_node)
{
$associated_nodes[] = $associated_node;
}
}
if(isset($result['AssociatedNode2']))
{
foreach($result['AssociatedNode2'] as $associated_node)
{
$associated_nodes[] = $associated_node;
}
}
$result['AssociatedNode'] = $associated_nodes;
}
}
unset($result);
return $results;
}
But this would force you to declare both AssociatedNode1 and AssociatedNode2 in the call to contain();
这篇关于HABTM与自己需要2x的行在连接表中?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!