How to implement a self-promotion model (parent_id) in cakephp

I have a table called categories. The table stores categories and their subtypes (subclauses) ...

Its a simple table:

  • ID
  • parent_id
  • title

That way I can create categories with infinite depth ... I was hoping cakephp would understand parent_id (I also tried category_id, but that makes cakePHP connect on its own: D)

What is the right way to handle this?

NOTE. There is also a many-many table called places. These places may belong to one or more categories.

+8
source share
6 answers

The behavior in the tree is too great for this situation. You just need to customize your model as follows:

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 that you find find () in the category, you will get two additional models called “Parent” (which points to the parent identifier) ​​and “Children” (which lists its children).

+21
source

Look at the behavior of the tree; with MPTT logic. The link provided to the Oracle website is dead; but you can find a ton of material on how to use it in cake guides and on the Internet .

 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 this structure for best results in Cake and its baking.

+5
source

In the category model: belongs to the parent and hasMany Children, both have the class "Category" and the foreign key "parent_id"

+2
source

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; } 
+1
source

RichardAtHome's answer is correct. In CakePHP 3. + you write:

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

and do not succumb to the use of the word “contain” in the “search”, for example:

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

A related question - suppose I have a hierarchy of self-regulation at 3 levels, implemented in accordance with the recommendation of @RichardAtHome - I understand that when I try to find a specific category, it will also get me the parent category and all child categories. However, how can I make him find the way back to the root? Is there any clean trick to accomplish this, or will a special hack be required?

I intend to use this in scenarios in which the Product table has one category identifier associated with it, but when displayed to users, I would also like to display the entire parent chain so that they can see something like "pastry / seasonal / nestle", - and then the user can change the entire hierarchy of products

0
source

Source: https://habr.com/ru/post/901150/


All Articles