Rekursives AR

Hallo Leute,

ich hab mal wieder ein Problem und zwar möchte ich Rekursiv auf eine Danktabelle zugreifen können.

Es sieht im Moment so aus das ich eine Tabelle Feld habe die einen Primärschlüsse (idFeld) und einen Fremdschlüssel (idParent) hat der wiederum auf einen Datensatz der Tabelle Feld verweist. Die Tabelle Feld hat noch weitere Attribute wie beispielsweise eine Bezeichnung. Ich möchte nun alle Datensätze in einem Art Baum ausgeben. Dazu rufe ich


$felder = Feld::model()->with('Kinder')->findAll('idParent IS NULL');

auf was mir die Felder geben sollte die die obersten Felder sind also die Eltern aller anderen Felder. Dazu sollte ich noch sagen das jedes Feld genau ein Elternfeld haben kann.

Die Relation (Kinder) ist im Moment folgendermaßen angelegt:


'Kinder' => array(self::HAS_MANY, 'Feld', 'idParent'),

Ich versuche in diesem ersten Schritt erstmal nur die Kinder der obersten Eltern abzurufen und noch nicht deren Kinder was ja dann mit:


'Kinder' => array(self::HAS_MANY, 'Feld', 'idParent', array('with'=>'Kinder')),

gehen sollte. Das Problem das ich im Moment habe ist das es gar nichts macht bzw. einen Fehler schmeißt der da lautet:


CDbCommand konnte das SQL-Statement nicht ausführen: SQLSTATE[23000]: Integrity constraint violation: 1052 Column 'idParent' in where clause is ambiguous

.

Da mir das nicht ganz unbekannt ist habe ich es auch schon mit


'Kinder' => array(self::HAS_MANY, 'Feld', 'Feld.idParent'),

versucht was aber wiederum zum Fehler:


Die Relation "Kinder" in der ActiveRecord-Klasse "Feld" wurde mit einem ungültigen Fremdschlüssel "Feld.idParent" definiert. In der Tabelle "Feld" gibt es keine solche Spalte.

Die Tabelle ist folgendermaßen aufgebaut:


CREATE TABLE IF NOT EXISTS `Feld` (

  `idFeld` int(11) NOT NULL AUTO_INCREMENT,

  `idParent` int(11) DEFAULT NULL,

  `Bezeichnung` varchar(40) NOT NULL,

  `Abkuerzung` varchar(4) NOT NULL,

  `Erstellt` int(11) NOT NULL,

  `Ersteller` int(11) NOT NULL,

  `Bearbeitet` int(11) DEFAULT NULL,

  `Bearbeiter` int(11) DEFAULT NULL,

  `Kommentar` text,

  PRIMARY KEY (`idFeld`),

  KEY `idParent` (`idParent`),

  KEY `Ersteller` (`Ersteller`),

  KEY `Bearbeiter` (`Bearbeiter`)

) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=5 ;

In der Datenbank sind die Relationen zwischen den Feldern und Tabellen angelegt, PHPmyadmin macht das aber irgendwie nicht so richtig gerade.

Habe ich irgendwo einen Denkfehler drin? Könnt ihr mir vielleicht sagen wo mein Denkfehler liegt und wie ich das lösen kann?

Grüße

Martin

Hallo Martin,

ich würde dir empfehlen von der Idee mit dieser Baumstruktur schnell Abstand zu nehmen.

Diese Art der Bäume findet SQL garnicht toll, da SQL auf Mengen basiert. Du müsstest für jede Ebene, die du tiefer gehst einen Self-Join machen und das ist nicht nur extrem unperformant, sondern erzeugt im Zusammenspiel mit Yii auch solche Probleme, wie du sie gerade hast :wink:

Aber es gibt natürlich eine Lösung und die heißt ‘Nested Sets’. Das ist quasi die Abbildung eines Baumes, wie du in konstruiert hast, als Mengen.

Und noch viel besser ist, dass es für Yii bereits ein Extension für Nested Sets gibt: http://www.yiiframework.com/extension/nestedsetbehavior/

Mit diesem Behavior erreichst du genau dein Ziel.

Schönen Gruß