在CakePHP树中查找子树

7
在CakePHP中,如何选择模型中actsAs树的子树?
我尝试了以下代码,以查找以label = "My Label"为头的树:
$this->find("threaded", array(
    "conditions" => array(
        "label" => "My Label"
    )
));

然而,查看日志后,它运行了以下SQL语句:

SELECT Menu.id, Menu.parent_id, Menu.lft, Menu.rght, Menu.label, Menu.link
FROM menus Menu
WHERE label = 'My Label'

很明显它只选择了一个节点,而不是它的所有子节点。
1个回答

15

看起来你需要像这样分成两个步骤来实现(来自手册):

$parent = $this->Category->find('first', array(
    'conditions' => array('label' => 'My label')
));
$parentAndChildren = $this->Category->find('threaded', array(
    'conditions' => array(
        'Category.lft >=' => $parent['Category']['lft'], 
        'Category.rght <=' => $parent['Category']['rght']
    )
));

threaded调用中,你不能使用'label' => 'my label'这个条件,因为它只会找到与该条件匹配的结果,包括父级和子级。 'threaded'仅根据parent_id重新排列普通查找操作的结果,所以你需要使用lft/rght列提供自己的"子代"条件。


是的,最终我几乎完全做了同样的事情 - 在组件中不包含这个功能似乎有点奇怪。 - nickf
我同意,这似乎是一个显而易见的用例。有 ->children() 但没有 ->childrenThreaded()。在模型类中查找,我认为你可以通过 $model->_findThreaded('after', null, $model->children($id)) 来实现,如果你按照 id 进行操作,但这似乎有点 hacky。 :o) - deceze
1
谢谢你的回答,我也希望有一种比这更简洁的方法。顺便说一下,如果你只想要子类别,你应该使用 'conditions' => array('Category.lft >' => $parent['Category']['lft'], 'Category.rght <' => $parent['Category']['rght']) 来避免再次获取父类别。 - bfncs
嗨,我该如何在视图中显示它?如果我有10个子级别要循环,我该怎么办... - Mico

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接