2011-11-09 15 views
6

Ho una tabella denominata categorie. La tabella contiene le categorie e le loro categorie (subsub) sub ...Come implementare un modello autoreferenziale (parent_id) in cakephp

La sua una tabella semplice:

  • id
  • parent_id
  • titolo

In questo modo posso fare categorie con profondità infinita ... speravo che cakephp capisse parent_id (ho anche provato category_id, ma questo rende cakePHP unirsi a se stesso: D)

Qual è il modo giusto per affrontare questo?

NOTA: Esiste anche una tabella chiamata "molti a molti". Quei posti possono appartenere a una o più categorie.

risposta

18

Il comportamento dell'albero è eccessivo per questa situazione. Hai solo bisogno di impostare il modello di come questo:

class Category extends AppModel { 

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

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

} 

Ora, quando si esegue un find() su Categoria, si otterrà due ulteriori modelli chiamato Parent (che punta al genitore id) e bambini (che elenca i suoi bambini).

+0

Ehi Richard, stavo cercando il comportamento dell'albero, ma sono d'accordo che può essere eccessivo. In ogni modo. Grazie per aver segnalato questo! –

2

Nella Categoria modello: Parent belongsTo e hasMany bambini, entrambi hanno la classe di 'Categoria' e chiave esterna 'parent_id'

5

sguardo al tree behaviour; con logica MPTT. Il collegamento fornito al sito Web di Oracle è morto; ma puoi trovare un po 'di materiale su come utilizzarlo su cake manual e 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) 
); 

Basta assicurarsi che il tavolo corrisponda a quella struttura per i migliori risultati entro torta ed è la cottura.

+0

Grazie uomo, roba interessante, e in effetti esattamente quello che mi serve. Tutto è impostato senza intoppi! –

+0

In molti casi questo è eccessivo. Una semplice tabella di auto-referenziazione come menzionato in seguito da Anh Pham con le associazioni appropriate è più che adeguata nella maggior parte delle cause. Il comportamento degli alberi diventa sempre più utile in quanto i livelli di "profondità" vanno oltre il livello (es .: i bambini possono avere figli). – pimbrouwers

0

Domanda correlata - presumo di avere una gerarchia autoreferenziale su 3 livelli implementata come consigliato da @RichardAtHome - Capisco quando cerco di trovare una particolare categoria, mi otterrà anche la categoria genitore e tutte le categorie di bambini. Tuttavia, come posso far sì che trovi il percorso di ritorno alla radice? C'è qualche trucco pulito per realizzare questo o richiederà un hack personalizzato?

Immagino di usarlo in uno scenario in cui la tabella Prodotto ha un ID di categoria associato ad esso, ma quando si visualizza agli utenti vorrei anche visualizzare l'intera catena parent in modo che possano vedere qualcosa come "dolci/stagionale/nestle '- e quindi l'utente può modificare l'intera gerarchia del prodotto

1

il seguente custom recursive function tree() lavorato per 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; 
} 
Problemi correlati