如何在cakephp中实现自引用(parent_id)模型

发布于 2024-12-14 13:23:01 字数 283 浏览 3 评论 0原文

我有一个名为类别的表。该表包含类别及其子(子子)类别...

它是一个简单的表:

  • idparent_id
  • title

这样我就可以制作具有无限深度的类别...我有点希望 cakephp 能够理解parent_id(我也尝试过category_id,但是 使 cakePHP 加入自身:D)

解决这个问题的正确方法是什么?

注意:还有一个名为“places”的“多对多”表。这些地点可以属于一个或多个类别。

I have a table called categories. The table holds categories and their sub(subsub)categories...

Its an easy table:

  • id
  • parent_id
  • title

This way I can make categories with endless depth... I kinda hoped that cakephp would understand parent_id (I also tried category_id, but that makes cakePHP join on itself :D )

What is the right way to tackle this?

NOTE: There is also a 'many to many' table called places. Those places can belong to one or more categories.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

看春风乍起 2024-12-21 13:23:01

对于这种情况,树的行为是多余的。您只需要像这样设置您的模型:

class Category extends AppModel {

  public $hasMany = array(
    'Children'=>array(
       'className'=>'Category',
       'foreignKey'=>'parent_id'
    )
  );

  public $belongsTo = array(
    'Parent'=>array(
       'className'=>'Category',
       'foreignKey'=>'parent_id'
    )
  );

}

现在,当您对 Category 执行 find() 时,您将获得两个额外的模型,称为 Parent(指向父 id)和 Children(列出其子项)。

Tree behaviour is overkill for this situation. You just need to set your model up like this:

class Category extends AppModel {

  public $hasMany = array(
    'Children'=>array(
       'className'=>'Category',
       'foreignKey'=>'parent_id'
    )
  );

  public $belongsTo = array(
    'Parent'=>array(
       'className'=>'Category',
       'foreignKey'=>'parent_id'
    )
  );

}

Now, when you do a find() on Category, you'll get two additional Models called Parent (which points to the parent id) and Children (which lists it's children).

泛滥成性 2024-12-21 13:23:01

看看树的行为;与 MPTT 逻辑。提供给 Oracle 网站的链接已失效;但您可以在蛋糕手册在线

CREATE TABLE categories (
    id INTEGER(10) UNSIGNED NOT NULL AUTO_INCREMENT,
    parent_id INTEGER(10) DEFAULT NULL,
    lft INTEGER(10) DEFAULT NULL,
    rght INTEGER(10) DEFAULT NULL,
    name VARCHAR(255) DEFAULT '',
    PRIMARY KEY  (id)
);

只需确保您的桌子与该结构相匹配,即可在蛋糕和烘焙中获得最佳效果。

Look at the tree behaviour; with MPTT logic. The link supplied to Oracle's website is dead; but you can find a bunch of material about how to use it on the cake manual and online.

CREATE TABLE categories (
    id INTEGER(10) UNSIGNED NOT NULL AUTO_INCREMENT,
    parent_id INTEGER(10) DEFAULT NULL,
    lft INTEGER(10) DEFAULT NULL,
    rght INTEGER(10) DEFAULT NULL,
    name VARCHAR(255) DEFAULT '',
    PRIMARY KEY  (id)
);

Just make sure your table matches that structure for best results within Cake and it's baking.

半窗疏影 2024-12-21 13:23:01

在类别模型中:belongsTo Parent 和 hasMany Children,都有类“Category”和外键“parent_id”

In Category model: belongsTo Parent and hasMany Children, both have the class 'Category' and foreign key 'parent_id'

遗心遗梦遗幸福 2024-12-21 13:23:01

以下自定义递归函数tree()对我有用

public function index() {
    $c = $this->tree();
    debug($c);
    exit;
}


function tree($parent=null){
    $arr  = array();
    $categories = $this->Category->find('all',array(
         'conditions'=>array('Category.parent_id '=> $parent)
    ));
    foreach($categories as $key => $category){           
        $arr[$category['Category']['id']]['title'] = $category['Category']['name'];             
        $arr[$category["Category"]["id"]]['children'] = $this->tree($category['Category']['id'] );
    }
    return $arr;
} 

the following custom recursive function tree() worked for me

public function index() {
    $c = $this->tree();
    debug($c);
    exit;
}


function tree($parent=null){
    $arr  = array();
    $categories = $this->Category->find('all',array(
         'conditions'=>array('Category.parent_id '=> $parent)
    ));
    foreach($categories as $key => $category){           
        $arr[$category['Category']['id']]['title'] = $category['Category']['name'];             
        $arr[$category["Category"]["id"]]['children'] = $this->tree($category['Category']['id'] );
    }
    return $arr;
} 
感性 2024-12-21 13:23:01

RichardAtHome 的答案是正确的。
在 CakePHP 3.+ 中,您可以这样写:

     $this->hasMany('Children', [
            'className'=>'Category',
            'foreignKey'=>'parent_id'
     ]);

    $this->belongsTo('Parent', [
        'className'=>'Category',
        'foreignKey'=>'parent_id'
    ]);

并且不要忘记在“查找”中使用“包含”,例如:

        $categories = $this->find("all")
           ->order(...)
           ->contain(['Children']);

RichardAtHome's answer is the right one.
In CakePHP 3.+ you write:

     $this->hasMany('Children', [
            'className'=>'Category',
            'foreignKey'=>'parent_id'
     ]);

    $this->belongsTo('Parent', [
        'className'=>'Category',
        'foreignKey'=>'parent_id'
    ]);

and don't forger to use 'contain' in your 'find', e.g.:

        $categories = $this->find("all")
           ->order(...)
           ->contain(['Children']);
櫻之舞 2024-12-21 13:23:01

相关问题 - 假设我按照 @RichardAtHome 的建议实现了 3 级自引用层次结构 - 我明白当我尝试查找特定类别时,它也会为我提供父类别和所有子类别。但是我怎样才能让它找到返回root的路径呢?是否有一些干净的技巧可以完成此任务,或者需要自定义黑客?

我想象在产品表有一个与其关联的类别 ID 的场景中使用此功能,但在向用户显示时我还想显示整个父链,以便他们可以看到类似“糖果/季节性/雀巢”之类的内容 - 然后用户可以更改整个产品层次结构

Related question - assume I have a 3 level self-referencing hierarchy implemented as advised by @RichardAtHome - I understand when I try to find a particular Category it will also get me the parent category and all children categories. However how can I make it find the path back to root? Is there some clean trick to accomplish this or will require a custom hack?

I imagine using this in a scenarios where the Product table has one category ID associated with it but when displaying to users I would like to also display the entire parent chain so that they can see something like 'confectionaries/seasonal/nestle' - and then the user can alter the entire product hierarchy

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文