2010-03-25 18 views
9

Ich versuche, ein Navigationssystem mit Kategorien Tabelle mit Hierarchien zu bauen. Normalerweise würde die Tabelle wie folgt definiert werden:MySQL & PHP - Mehrere Eltern Kind Beziehungen erstellen

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

Aber der Haken ist, dass ich verlangen, dass eine Kategorie Kind zu mehreren Kategorien Eltern sein kann .. Genau wie ein Hat und gehört Viel (HABTM) Beziehung.

Ich weiß, dass, wenn es zwei Tabellen, Kategorien & Elemente gibt, wir eine Join-Tabelle categories_items verwenden, um die HABTM-Beziehungen aufzulisten. Aber hier habe ich keine zwei Tische, sondern nur Tische, aber sollte irgendwie HABTM-Beziehungen zu sich selbst zeigen. Ist dies mit einer einzigen Tabelle möglich? Wenn ja, wie? Wenn nicht möglich, welche Regeln (Tabellennamen, Felder) sollte ich beim Erstellen der zusätzlichen Join-Tabelle beachten?

Ich versuche, dies mit CakePHP zu erreichen, wenn jemand CakePHP Lösung für dieses Problem bieten kann, das wäre genial. Auch wenn das nicht möglich ist, wird jede Lösung zum Erstellen einer Join-Tabelle geschätzt. Vielen Dank für Ihre Zeit.

- Bearbeiten - Meine Frage scheint ein wenig verwirrend zu sein, also versuche ich, das, was ich suche, zu wiederholen. In traditionellen Self-Join-Beziehungen (Self-Join) mit Eltern-Kind-Beziehungen kann jedes Element nur einen Elternteil haben. Ich suche nach einer HABTM-Beziehung, d.h. mehreren Eltern für jeden Gegenstand.

Kategorien & Elemente - Um HABTM zu definieren, verwenden wir categories_items Join-Tabelle.

Wenn innerhalb von Kategorien ich HABTM brauche, was soll ich tun?

+0

u kann durch getrennt sie durch Komma oder ein seperator –

+0

+1 interessante Frage :-) – richsage

+0

ich dies in einem Feld mit mehreren Werten speichern gefunden, während googeln, http://n2.nabble.com/Saving-self- referential-HABTM-relations-td1126141.html, ich habe versucht, das selbe zu replizieren, aber trotzdem fängt Cake die Verbindung nicht ein. Irgendeine Idee, jemand? – Ashok

Antwort

0

es endlich.

Naviitems Tabelle:

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`) 
); 

Selbst Join-Tabelle:

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 Modell:

<?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' => '' 
     ) 
    ); 
} 
?> 

ich den Regler und Ansichten mit Kuchen backen Schale erzeugt haben. Es funktioniert jetzt gut. Danke für all die Ideen, die du beigetragen hast, sie haben mir sehr geholfen.

0

Was Sie versuchen zu erreichen, ist nicht wirklich ein Kuchen Weg Ansatz. Sie sollten zwei Tabellen mit einer Join-Tabelle zwischen verwenden. Kuchens Maxime ist "Konvention über Konfiguration", also solltest du wirklich den Standard-Kuchen-Weg benutzen.

Um den HABTM zu erstellen, werden Sie drei Tabellen benötigen.

items 
categories 
categories_items 

Artikel und Kategorie sind wie erwartet. Ihre Join-Tabelle sollte nur enthalten die beiden IDs der verknüpften Tabellen wie folgt

category_id 
item_id 

Dies ermöglicht es Ihnen, ein Navigationselement in mehreren Kategorien erscheinen zu haben, sollten Sie dies wünschen.

Weitere Informationen finden Sie im Buch zu finden, http://book.cakephp.org/view/1044/hasAndBelongsToMany-HABTM

+0

Heads-up: Ashok hat nicht zwei Tische, sondern einen, der sich auf sich selbst bezieht. :) – pinkgothic

+0

Dies ist der "Kuchen Weg" wie in der Frage gefragt :) –

+0

Sie missverstanden meine Frage ... Ich versuche nicht, eine HABTM zwischen Kategorien und Elementen zu erstellen ... Ich versuche, eine HABTM innerhalb erstellen Kategorien Tabelle. – Ashok

2

Der Versuch, eine n drücken: m-Beziehung (HABTM) in eine 1: n-Beziehung ist keine gute Praxis, und Sie werden in Grenzen führen würden Sie nicht Haben Sie es sauber gemacht, aber so können Sie es machen (generisches PHP, nicht CakePHP-spezifisch):

Sie können eine Spalte in Ihrer Tabelle erstellen, um alle Eltern-IDs in einer durch Kommas getrennten Liste zu speichern. Sie können die einzelnen IDs aus, indem Sie lesen ...

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

... und schreiben Sie sie wieder in die Spalte ...

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

Actual read-write der Datenbank würde passieren, bevor/nach diesen Schnipsel.


Wenn Sie es richtig zu machen, Sie möchten, dass Sie Haupt-Tabelle wie folgt aussehen:

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

Und Ihre n: m-Beziehung Tabelle wie folgt aussehen:

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

Sie würde es so abfragen:

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 ... 

Genau das, was Sie wollen WHERE und Ihre SELECT wird bis zu dem, was Sie erhoffen sich zu erreichen. Ob Sie wollen LINKS OUTER JOIN oder INNER JOIN, das hängt davon ab, ob Sie Kategorien in m. * Zurückgeben wollen, die keinen Eintrag in Ihrer Beziehungstabelle haben (= keine Eltern haben). Wenn Sie neu bei der Syntax sind, werfen Sie einen Blick auf this Wiki article on joins.

+0

Danke, das war hilfreich. – Ashok

1

Dies ist fast genau das, was die Tree behaviour ist. Das Verhalten basiert auf MPTT (Modified Preorder Tree Traversal). Sie würden es so konfigurieren:

Fügen Sie die folgenden Felder auf dem Tisch:

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

Modell:

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

Sie dann eine parent_id <select> in Ihrer Kategorie-Modifikationsformen bauen würde, und das Tree-Verhalten würde sich um den Rest kümmern. Ich nehme an, Sie könnten die Neuordnung von Kategorien innerhalb einer Ebene Ihrer Kategoriehierarchie manuell handhaben, aber Sie sind wahrscheinlich besser dran mit den Methoden moveUp und moveDown, die in Modellen verfügbar sind, die mit dem Tree-Verhalten erweitert wurden.

Hier ist auch eine nützliche zum Konvertieren der Baumlisten in geordnete/ungeordnete Listen in Ihren Ansichten.

+1

Hallo, aber auch das Tree-Verhalten behandelt nicht mehrere Eltern-Kind-HABTM-Beziehungen. In dem Link, den Sie gegeben haben, http://book.cakephp.org/view/91/Tree, wie Sie sehen können, dass jede Kategorie nur einmal eine Unterkategorie sein kann. Mit anderen Worten, jede Kategorie kann nur einen Elternteil haben. Was ich suche, ist mehrere Eltern für jede Kategorie ... – Ashok

+0

Oof, ich habe dich falsch gelesen. Entschuldigen Sie. –

3

Ich hoffe, es ist keine schlechte Form, ein zweites Mal zu antworten, die Frage beim ersten Mal missverstanden. Das Folgende ist im Wesentlichen eine CakePHP-Implementierung von pinkgothic's Antwort.

New HABTM Join-Tabelle:

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 im Modell:

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

Hallo, Danke, dass du versucht hast, mir zu helfen, aber ich fürchte, der Code hat nicht funktioniert. Cake hat die Verbindung nicht verstanden. Wenn Sie ein Element hinzufügen, zeigt es keine Option zur Auswahl einer Eltern-ID. – Ashok

+0

Danke für die Eingabe Hobonium, ich konnte die Lösung durch einige Modifikationen von Ihrem Code bekommen. Ich habe es hier hingelegt. – Ashok