2010-03-25 22 views
9

Sto provando a creare un sistema di navigazione utilizzando la tabella delle categorie con gerarchie. Normalmente, la tabella verrebbe definito come segue:MySQL e PHP - Creazione di più relazioni padre figlio

id (int) - Primary key 
name (varchar) - Name of the Category 
parentid (int) - Parent ID of this Category referenced to same table (Self Join) 

Ma il problema è che ho bisogno che una categoria può essere bambino a più categorie padre .. Proprio come un ha e appartiene a più (HABTM) relazione.

So che se ci sono due tabelle, categorie & voci, usiamo una tabella di join categories_items per elencare le relazioni HABTM. Ma qui non sto avendo due tavoli ma solo una tabella, ma in qualche modo dovrei mostrare le relazioni HABTM a se stesso. È possibile utilizzare un solo tavolo? Se sì, come? Se non è possibile, quali regole (denominazione delle tabelle, campi) dovrei seguire durante la creazione della tabella di join aggiuntiva?

Sto cercando di ottenere questo risultato utilizzando CakePHP, se qualcuno può fornire la soluzione CakePHP per questo problema, sarebbe fantastico. Anche se ciò non è possibile, qualsiasi soluzione sulla creazione della tabella di join è apprezzata. Grazie per il tuo tempo.

- Modifica - La mia domanda sembra essere un po 'confusa, quindi sto cercando di rideterminare quello che sto cercando. Nelle relazioni genitore-figlio (self join) con riferimento personale (self join), ogni elemento può avere un solo genitore. Quello che sto cercando è simulare una relazione HABTM, cioè più genitori per ogni oggetto.

Categorie & Elementi: per definire HABTM, viene utilizzata la tabella di join di categories_items.

Se all'interno delle Categorie ho bisogno di HABTM, cosa devo fare?

+0

u può salvare i valori multipli in un campo da loro separati da virgola o qualche separatore –

+0

+1 domanda interessante :-) – richsage

+0

Ho trovato questo mentre googling, http://n2.nabble.com/Saving-self- referenziale-HABTM-relationships-td1126141.html, ho provato a replicare lo stesso, ma ancora Cake non sta prendendo l'associazione. Qualche idea, qualcuno? – Ashok

risposta

0

Got finalmente.

Naviitems Tabella:

CREATE TABLE IF NOT EXISTS `naviitems` (
    `id` int(11) NOT NULL AUTO_INCREMENT, 
    `name` varchar(50) NOT NULL, 
    `linkurl` varchar(250) NOT NULL, 
    PRIMARY KEY (`id`) 
); 

Auto Registrazione Tabella:

CREATE TABLE IF NOT EXISTS `naviitems_parents` (
    `id` int(11) NOT NULL AUTO_INCREMENT, 
    `naviitem_id` int(11) NOT NULL, 
    `parent_id` int(11) NOT NULL, 
    PRIMARY KEY (`id`) 
); 

Naviitems Modello:

<?php 
class Naviitem extends AppModel { 

    var $name = 'Naviitem'; 

    //The Associations below have been created with all possible keys, those that are not needed can be removed 
    var $hasAndBelongsToMany = array(
     'Parent' => array(
      'className' => 'Naviitem', 
      'joinTable' => 'naviitems_parents', 
      'foreignKey' => 'naviitem_id', 
      'associationForeignKey' => 'parent_id', 
      'unique' => true, 
      'conditions' => '', 
      'fields' => '', 
      'order' => '', 
      'limit' => '', 
      'offset' => '', 
      'finderQuery' => '', 
      'deleteQuery' => '', 
      'insertQuery' => '' 
     ) 
    ); 
} 
?> 

ho generato il Controller e Vista usando le coperture Cake Bake. Sta funzionando bene ora. Grazie per tutte le idee che hai contribuito, mi hanno aiutato molto.

0

Quello che stai cercando di ottenere non è un approccio alla torta. Dovresti utilizzare due tabelle con una tabella di join tra. La massima di Cake è "convenzione sulla configurazione", quindi dovresti davvero usare la torta standard.

Per creare l'HABTM, vorrai tre tabelle.

items 
categories 
categories_items 

L'articolo e la categoria sono come ti aspetteresti. Il vostro tavolo aderire deve solo contenere i due id delle tabelle unite come segue,

category_id 
item_id 

Questo vi permetterà di avere un elemento di navigazione appaiono in più categorie, si deve in modo da scegliere.

Maggiori informazioni si possono trovare nel libro, http://book.cakephp.org/view/1044/hasAndBelongsToMany-HABTM

+0

Heads-up: Ashok non ha due tabelle, ma una che si riferisce a se stessa. :) – pinkgothic

+0

Questa è la "torta" come richiesto nella domanda :) –

+0

Hai frainteso la mia domanda ... Non sto cercando di creare un HABTM tra Categorie ed Elementi ... Sto cercando di creare un HABTM all'interno Tabella delle categorie. – Ashok

2

cercando di spremere un n: m rapporto (HABTM) in un 1: n relazione non è buona pratica e si incorrerà in limitazioni che non lo farei se lo hai fatto in modo pulito, ma è così che potresti farlo (PHP generico, non specifico per CakePHP):

Puoi creare una colonna nella tua tabella per memorizzare tutti gli ID padre in un elenco separato da virgole. È possibile leggere le singole ID con l'ausilio di ...

$ids = explode(',', $idsFromColumn); 

... e scriverle di nuovo nella colonna utilizzando ...

$idsForColumn = implode(',', $ids); 

effettiva lettura-scrittura del database sarebbe successo prima/dopo quei frammenti, rispettivamente.


Se si vuole fare in modo corretto, si vuole si tabella principale a questo aspetto:

id (int) - Primary key 
name (varchar) - Name of the Category 

E il tuo n: rapporto m tabella simile a questa:

id (int) - child 
parentid (int) - parent 

Lo chiederai in questo modo:

SELECT ... 
FROM 
    main_table AS m 
    [LEFT OUTER|INNER] JOIN 
    relationship_table AS r 
     ON r.id=m.id 
    [LEFT OUTER|INNER] JOIN 
    main_table AS n 
     ON r.parentid=n.id 
WHERE ... 

Esattamente quello che vuoi in te DOVE e il tuo SELECT saranno all'altezza di ciò che speri di ottenere. Per quanto riguarda il fatto che tu voglia LEFT OUTER JOIN o INNER JOIN, che dipende dal fatto che si desideri restituire le categorie in m. * Che non hanno una voce nella relazione_tabella (= non hanno alcun genitore). Se sei nuovo per unirti alla sintassi, dai uno sguardo allo this Wiki article on joins.

+0

Grazie, questo è stato utile. – Ashok

1

Questo è quasi esattamente ciò per cui è progettato il Tree behaviour. Il comportamento si basa su MPTT (Modified Preorder Tree Traversal). Si potrebbe configurare così:

aggiungere i seguenti campi al vostro tavolo:

`parent_id` int(10) unsigned default NULL 
`lft` int(10) unsigned default NULL 
`rght` int(10) unsigned default NULL 

Modello:

class Category extends AppModel 
{ 
    var $actsAs = array('Tree'); 
} 

Farebbe quindi costruire un parent_id <select> nelle vostre forme categoria-modifica, e il comportamento dell'albero si prenderà cura di tutto il resto. Suppongo che tu possa gestire manualmente il riordino di categorie all'interno di un livello della tua gerarchia di categorie, ma probabilmente stai meglio usando i metodi moveUp e moveDown disponibili nei modelli estesi con il comportamento Tree.

Qui, inoltre, è un utile Tree Helper per convertire gli elenchi di alberi in elenchi ordinati/non ordinati nelle viste.

+1

Salve, ma anche il comportamento Tree non gestisce più relazioni HABTM secondarie padre. Nel link che hai fornito, http://book.cakephp.org/view/91/Tree, come puoi vedere ogni categoria può essere una sottocategoria solo una volta .. In altre parole, ogni categoria può avere solo un genitore. Quello che sto cercando sono i genitori multipli per ogni categoria ... – Ashok

+0

Oof, ho frainteso te. Mie scuse. –

3

Spero che non sia una cattiva forma rispondere una seconda volta, avendo frainteso la domanda la prima volta. Quanto segue è essenzialmente un'implementazione di CakePHP della risposta di pinkgothic.

Nuova HABTM join tabella:

CREATE TABLE `categories_parent_categories` (
    `category_id` int(10) unsigned NOT NULL, 
    `parent_category_id` int(10) unsigned default NULL, 
    `order` int(10) unsigned NOT NULL default '0' 
); 

Association nel modello:

class Category extends AppModel 
{ 
    var $hasAndBelongsToMany = array(
     'ParentCategory' => array(
      'className'    => 'Category', 
      'joinTable'    => 'categories_parent_categories', 
      'foreignKey'   => 'category_id', 
      'associationForeignKey' => 'parent_category_id', 
      'order'     => 'CategoriesParentCategory.order' 
     ) 
    ); 
} 
+0

Ciao, grazie per aver cercato di darmi una mano, ma temo che il codice non abbia funzionato .. Cake non ha catturato l'associazione. Quando aggiungi un elemento, non mostra l'opzione per selezionare un id genitore. – Ashok

+0

Grazie per l'input Hobonium, sono riuscito a ottenere la soluzione con alcune modifiche dal tuo codice. L'ho postato qui. – Ashok

Problemi correlati