Anzeige Von Daten Aus Einer Has_Many Beziehung

Hallo,

ich schaffe das einfach nicht - trotz Studium des Manual Artikels über Relationale Active Records:

Tabelle Sammelhefte ist mit Tabelle Noten verknüpft und Noten mit [b]Komponisten:

[/b]




// model Sammelhefte

public function relations()

{

        return array(

            'Werke'=>array(self::HAS_MANY, 'Noten', 'Sammelheft_Id'),

        );

}

Tabelle Noten ist mit Komponisten verknüpft:




// model Noten

public function relations() {

    return array(

        'Komponist'=>array(self::BELONGS_TO, 'Komponisten', 'Komponist_Id'),

        );

}

Ich möchte zu jedem Datensatz in der Tabelle Sammelhefte alle Komponistennamen mit einer Funktion ausgeben.


public function getComposerList () { 

   $Werke = Noten::model()->with("Komponist")->findByAttributes(array("Sammelheft_Id"=>$this->Id));

   $KomponistenListe = "";

   if ( is_array ($Werke)) {

 	foreach ( $Werke as $Werk ) $KomponistenListe .= $Werk->Zuname."\n";

   }

   return $KomponistenListe;

}



Alle meine Versuche scheiterten an diversen Fehlermeldungen. Die Funktion GetComposerList liefert zwar keinen Fehler aber auch keine Daten, Das Array ist also offensichtlich leer.

Habe jetzt eine längere Pause mit Yii gemacht und stehe leider wieder da wie am Anfang :angry:

Danke im Voraus für jede Hilfe.

Ferdinand

für mich logisch müsste in die komponentenliste $Werk->Komponist->Zuname

und $werk->Zuname schmeisst keinen Fehler? wundert mich.

Der Fehler lag darin, dass es in der Tabelle Sammelhefte offensichtlich auch Datensätze gibt, bei denen die Komponist_Id NULL ist. Das habe ich nun abgefangen. Es funktioniert jetzt mit folgendem Code.


public function getComposerList () {

  $Werke = Noten::model()->with("Komponist")->findAll(array("condition"=>"Sammelheft_Id=".$this->Id));

  $KomponistenListe = "";

  foreach ( $Werke as $Werk ) {

      if ( $Werk->Komponist_Id ) {

          $Name = $Werk->Komponist->Vorname." ".$Werk->Komponist->Zuname;

          $KomponistenListe .= $Name.", ";

      }

  }

  return rtrim($KomponistenListe,", ");

}



Was mir jetzt noch fehlt:

Jeder Komponist sollte in der Liste nur einmal vorkommen. Wie kann ich das mit Yii in die Parameter von findAll() einbauen? Das Problem ist, dass die Übereinstimmung über 2 Felder (Vorname und Zuname) gehen muss. Oder muss ich das selber mit PHP irgendwie hinzaubern?

als erstes erstellst du eine methode im komponist-Model:




public function getFullname()

{

  return sprintf('%s %s, $this->Vorname, $this->Zuname);

}



dann sieht deine getComposerList zunächst so aus




public function getComposerList () {

  $Werke = Noten::model()->with("Komponist")->findAll(array("condition"=>"Sammelheft_Id=".$this->Id));

  $KomponistenListe = "";

  foreach ( $Werke as $Werk ) {

      if ( $Werk->Komponist ) {

          $KomponistenListe .= $Werk->Komponist->fullname .", ";

      }

  }

  return rtrim($KomponistenListe,", ");

}



weiter




public function getComposerList ()

{

  $Werke = Noten::model()->with("Komponist")->findAll(array("condition"=>"Sammelheft_Id=".$this->Id));


  $KomponistenListe = array(); // array statt string verkettung


  foreach ( $Werke as $Werk ) {

      if ( $Werk->Komponist ) {

          if (!in_array($Werk->Komponist->fullname), $KomponistenListe) {

            $KomponistenListe[] = $Werk->Komponist->fullname;

          }

      }

  }


  return implode(', ', $KomponistenListe);

}



Danke herzlich für die Hilfe.

Der noch leicht abgeänderte Code zeigt mir die Liste der Komponisten in der CGridView korrekt an:




// Methode im model Komponisten:

public function getFullNameCommon() {

  	return sprintf('%s %s', $this->Vorname, $this->Zuname);

}


// Methode im model Sammelhefte:

public function getComposerList () {

$Werke = Noten::model()->with("Komponist")->findAll(array("condition"=>"Sammelheft_Id=".$this->Id));

	$KomponistenListe = array(); 

	foreach ( $Werke as $Werk ) {

		if ( $Werk->Komponist ) {

			$Komponist = $Werk->Komponist->fullNameCommon;

			if (! in_array($Komponist, $KomponistenListe)) {

				$KomponistenListe[] = $Komponist;

			}

		}

	}

	return implode(', ', $KomponistenListe);

}

Wie kann ich nun diese Komponistenliste, die von obiger Funktion bei jedem Datensatz im GridView Sammelhefte ausgegeben wird, für die Suche verwenden?

Folgendes scheitert jedenfalls:




public function search() {

    $criteria=new CDbCriteria;

    $criteria->compare('t.Id',$this->Id);

    $criteria->compare('Liste_Komponisten',$this->composerList,true);