Empfehlungen: Erweiterte Suche

CustomBehavior

Anleitungen und Quellcode-Auszüge die den Start vereinfachen sollen.

CustomBehavior

Beitragvon havanna » Do 30. Okt 2008, 23:27

Hallo,
wie ich im Beitrag zum Custom Pagination geschrieben habe, ist die automatische Tabellenverknüpfung in CakePHP auch mit Nachteilen verbunden.
Neben der Schwierigkeit, die Seiten zu nummerieren, resultieren daraus ggf. Laufzeitprobleme. Da ich auch in die Richtung "recursive" und "unbind" recherchiert hatte, um mein Problem zu lösen, bin ich auf die CustomBehavior gestossen.

Ab 1.2.0.7692 RC2 funktioniert das wohl auch, was in der CakePHP Dokumentation steht. Da die meisten Informationen dazu nur in englisch vorliegen, habe ich noch eine kleine Doku zu dieser Erweiterung geschrieben.

Hier wieder als PDF.

Ciao Thomas

P.S. Ich publiziere diese Dokus exklusive hier in diesem Forum. Es wäre schön, einmal Resonanz dazu zu erhalten
Benutzeravatar
havanna
 
Beiträge: 191
Registriert: Mi 15. Okt 2008, 23:12
Wohnort: Bodman-Ludwigshafen
CakePHP-Version: 1.2.x
OS: WIN

Re: CustomBehavior

Beitragvon Alex » Fr 31. Okt 2008, 09:53

Hi Thomas,

das ist echt super, was du da gemacht hast. Allerdings verstehe ich nicht ganz. Es geht wahrscheinlich um was ganz anderes, aber wenn du in einem find('all') die Felder mitgibst, welche ausgelesen werden sollen, dann werden auch nur diese ausgelesen. Wenn du verhindern willst, dass NULL-Einträge ignoriert werden, dann kannst du das doch in den Conditions angeben.
Alex
 
Beiträge: 120
Registriert: Di 13. Mai 2008, 13:39
Wohnort: Bremen
CakePHP-Version: 1.x.x
OS: OSX / Win 7 / Debian

Re: CustomBehavior

Beitragvon Tobitobe » Fr 31. Okt 2008, 11:57

Sehr schön. Je mehr deutsches Material, desto besser. ;-)

Aber wie wäre es, wenn Du die entsprechenden Seiten im Manual für die gesamte Community übersetzen würdest?
Dann hätten nicht nur wir Forenuser etwas davon.
Tobitobe
 
Beiträge: 45
Registriert: Mi 11. Jun 2008, 08:41
Wohnort: Neuss
CakePHP-Version: 1.2.0.7962 Final
OS: Mac OS X

Re: CustomBehavior

Beitragvon havanna » Fr 31. Okt 2008, 17:28

Hi Alex,
du hast Recht, dass es da Überschneidung gibt mit anderen Parametern, die in find verwendet werden können.
Du siehst den Unterschied, wenn du dir das erzeugte SQL-Kommando ansiehst. Nehmen wir als Beispiel mein Immobilien-Modell: Wenn ich anstatt dem CustomBehavior die Reduktion über fields vornehmen, sieht mein Aufruf als Beispiel wie folgt aus:

Code: Alles auswählen

    $eintraege = $this->Immobilien->find('all',array(
      'fields' => array('immobilien.objektnummer',
        'immobilien.plz',
        'immobilien.ort',
        'immobilien.strasse',
        'immobilien.stichwort',
        'anhaenge.pfad',
        'anhaenge.gruppe'),
      'group' => array('Immobilien.objektnummer')
      ));


Das erzeugte SQL-Kommando sieht dann so aus:
Code: Alles auswählen

SELECT `immobilien`.`objektnummer` , `immobilien`.`plz` , `immobilien`.`ort` , `immobilien`.`strasse` , `immobilien`.`stichwort` , `anhaenge`.`pfad` , `anhaenge`.`gruppe`
FROM `immobilien` AS `Immobilien`
LEFT JOIN `immobilienart` AS `Immobilienart` ON ( `Immobilien`.`immobilienart` = `Immobilienart`.`id` )
LEFT JOIN `anhaenge` AS `Anhaenge` ON ( `Anhaenge`.`objektnummer` = `Immobilien`.`objektnummer` )
LEFT JOIN `freitexte` AS `Freitexte` ON ( `Freitexte`.`objektnummer` = `Immobilien`.`objektnummer` )
WHERE 1 =1
GROUP BY `Immobilien`.`objektnummer`


So, und nun schau' dir (unten) den Screenshot aus phpMyAdmin dazu an, wenn ich das GROUP BY weg lasse. Du siehst, dass es jetzt keine Null-Einträge gibt, denn es sind alle Felder gefüllt, aber es gibt als Ergebnis jeden Eintrag zig-fach, da MySQL im Hintergrund die über das Modell verbundenen (aber nicht im Array fields enthaltenen) Tabellen immobilienart und freitexte berücksichtigt.

Du wirst, wenn du im Internet zum Thema Unbind und CustomBehavior recherchierst, einige Beiträge finden, in denen Anwender die Grenzen der Datenbank durch dieses autom. Einbinden gesprengt haben, da MySQL intern zuerst die Datensätze selektiert und erst dann durch GROUP BY verdichtet - sofern der Befehl mitgegeben wird.

Aber: einen Haken hat die Sache noch: Möchte man fields und CustomBehavior kombinieren, muss man "unnötige" rendundante Angaben machen. Ein funktionierender Aufruf, der sowohl die Felder des aufgerufenen Modell einschränkt, als auch die durch CustomBehavior sieht dann z.B. so aus:
Code: Alles auswählen

       $this->paginate['Immobilien'] = array(
        'limit' => 5,
        'conditions' => $conditions,
        'recursive' => 0,
        'fields' => array('Immobilien.objektnummer',
          'Immobilien.plz',
          'Immobilien.strasse',
          'Immobilien.ort',
          'Immobilien.gesamtpreis',
          'Immobilien.stichwort',
          'Immobilien.mietekauf',
          'Immobilien.iso_waehrung',
          'Immobilien.nettokaltmiete',
          'Anhaenge.objektnummer',
          'Anhaenge.pfad',
          'Anhaenge.gruppe',
          'Anhaenge.anhangtitel'),
        'contain' => array(
          'Anhaenge' => array(
            'fields' => array('Anhaenge.objektnummer','Anhaenge.pfad','Anhaenge.gruppe','Anhaenge.anhangtitel')
          )
        ),
        'group' => 'Immobilien.objektnummer');
 


Das Ergebnis ist dann allerdings, dass man ein sehr sauberes SQL-Kommando hat, das sich auf das beschränkt, was man benötigt. Eben so, wie man es "von Hand" machen würde:

Code: Alles auswählen

SELECT `Immobilien`.`objektnummer`, `Immobilien`.`plz`, `Immobilien`.`strasse`, `Immobilien`.`ort`, `Immobilien`.`gesamtpreis`, `Immobilien`.`stichwort`, `Immobilien`.`mietekauf`, `Immobilien`.`iso_waehrung`, `Immobilien`.`nettokaltmiete`, `Anhaenge`.`objektnummer`, `Anhaenge`.`pfad`, `Anhaenge`.`gruppe`, `Anhaenge`.`anhangtitel` FROM `immobilien` AS `Immobilien` LEFT JOIN `anhaenge` AS `Anhaenge` ON (`Anhaenge`.`objektnummer` = `Immobilien`.`objektnummer`)  WHERE `Immobilien`.`plz` LIKE "%" AND `Immobilien`.`immobilienart` = 1  GROUP BY `Immobilien`.`objektnummer`
 


Und selbst wenn ich hier das GROUP BY unterlasse, erhalte ich keine unnötigen Einträge und belaste damit die Datenbank so wenig wie möglich. Wenn ich Zeit habe, werde ich mal die unterschiedlichen Rückantwortzeiten messen.

@Tobitobe: Danke, dass du mir das zutraust. Doch dazu fühle ich mich (noch) nicht berufen.

Ciao Thomas

Bild
Benutzeravatar
havanna
 
Beiträge: 191
Registriert: Mi 15. Okt 2008, 23:12
Wohnort: Bodman-Ludwigshafen
CakePHP-Version: 1.2.x
OS: WIN


Zurück zu Tutorials und Snippets

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 1 Gast