Suche in verschiedenen Models/Tabellen

58 views
Skip to first unread message

Andreas

unread,
May 19, 2007, 6:24:08 AM5/19/07
to CakePHP-de für deutsche CakePHP Entwickler
Hallo,

ich habe erst vor kurzem CakePHP für mich entdeckt und stoße da doch
noch recht schnell an meine Grenzen.

Ich möchte eine Suche bereitstellen die sich aber leider nicht nur auf
ein Model bzw. eine Tabelle bezieht
Als Beispiel: Ich habe 2 Models (+2 Controller +2 DB-Tabellen) "City"
und "Street". Jetzt will ich auf einer Seite eine Such bereitstellen
die in beiden Tabellen nach passenden Einträgen sucht. (eine Suche
nach "Berlin", findet also sowohl die Stadt Berlin als auch Straßen
die "Berlin" heißen.

Also habe ich mir einen Controller SearchController gebastelt deren
Index-Action in den beiden Tabellen suchen sollte - geht aber
natürlich nicht da es kein Search-Model gibt...

Wie löst man das? Ich möchte die Suche eigentlich nicht einem der
beiden Controller Strasse/Stadt zuweisen weil es ja eigentlich zu
beiden gehört und ich auch am liebsten in der URL statt citys/
search/... eben /search/... stehen hätte.

Ich hoffe mein Problemist klargeworden.

Danke
Andreas

Dirk Olbertz

unread,
May 19, 2007, 5:40:21 PM5/19/07
to CakePHP-de für deutsche CakePHP Entwickler
Hi Andreas,

> Ich möchte eine Suche bereitstellen die sich aber leider nicht nur auf
> ein Model bzw. eine Tabelle bezieht
> Als Beispiel: Ich habe 2 Models (+2 Controller +2 DB-Tabellen) "City"
> und "Street". Jetzt will ich auf einer Seite eine Such bereitstellen
> die in beiden Tabellen nach passenden Einträgen sucht. (eine Suche
> nach "Berlin", findet also sowohl die Stadt Berlin als auch Straßen
> die "Berlin" heißen.
>
> Also habe ich mir einen Controller SearchController gebastelt deren
> Index-Action in den beiden Tabellen suchen sollte - geht aber
> natürlich nicht da es kein Search-Model gibt...
>
> Wie löst man das? Ich möchte die Suche eigentlich nicht einem der
> beiden Controller Strasse/Stadt zuweisen weil es ja eigentlich zu
> beiden gehört und ich auch am liebsten in der URL statt citys/
> search/... eben /search/... stehen hätte.

Ob Du einen Search-Controller benötigst, weiß ich gar nicht mal so
genau. Da wäre ich auch noch auf Input anderer hier gespannt. Aus
technischer Sicht benötigst Du ihn nicht, aber eventuell sind die
einzelnen Funktionalitäten so besser getrennt.

Im Kopf des Controllers sagst Du ja immer
var $uses = array('ModelName');

Also z.B. im StreetController
var $uses = array('Street');

Somit kannst Du dann im Controller über $this->Street auf Dein Model
zugreifen.

Du kannst in dem Array aber auch noch beliebige andere Models mit
aufnehmen, also z.B. im StreetController
var $uses = array('Street', 'City');

Jetzt kannst Du über $this->City auch auf dieses Model zugreifen. Es
ist gerade die Aufgabe des Controllers, die Daten mehrerer Models zu
verarbeiten und an ein View zu geben.

Wenn Du aber - wie ich es in Deinem Fall annehme -, eine Relation
zwischen zwei Models geknüpft hast, musst Du aber im Controller das
zweite Model gar nicht mit angeben.

Beispiel:

CityModel:
var $hasMany = array('Street');
# Eine Stadt hat mehrere Straßen

StreetModel
var $belongsToMany = array('City');
# ein Straßenname kann in mehreren Städten vorkommen.

Jetzt reicht es z.B. im StreetController aus, nur das StreetModel zu
benutzen:
var $uses = array('Street');

Trotzdem kannst Du im StreetModel nicht nur mittels $this->Street auf
das StreetModel, sondern mittels $this->Street->City auch auf das
CityModel zugreifen. Das nennt man "Chaining" und ist ziemlich
nützlich, weil man so nur in den Models die Relationen definiert.

Bei mehr Relationen kann es hier aber Performance-Probleme geben. Lies
Dir deshalb am Besten auch noch
http://cakebakery.de/2007/02/16/fallstricke-bei-den-model-relationen/
durch. Da habe ich das mal etwas genauer erläutert und auch einen
Ausweg gezeigt. In Cake 1.2 wird das dort beschriebene expects() nicht
mehr benötigt, sondern wird durch etwas noch flexibleres ersetzt.

Jetzt aber zurück zu Deiner Ausgangsfrage. Wenn Du ein
SearchController erstellst, kannst Du dort einfach ein
var $uses = array('Street');
angeben, um auf das StreetModel und über Chaining auf das CityModel
zuzugreifen.

Du könntest die Suche rein technisch auch in einem der beiden Models
machen, aber da hast Du schon Recht, dass dann nie so klar ist, wo das
denn nun eigentlich hin soll. Die "/search/"-Route kannst Du in der
routes.php aber auch ohne einen SearchController anlegen.

Ich hoffe, das hat Dir erst einmal weiter geholfen.

Gruß,
Dirk


Timo Derstappen

unread,
May 20, 2007, 6:52:32 AM5/20/07
to cakep...@googlegroups.com
Also der SearchesController (man beachte die Cake Konventionen :))
macht Sinn, wenn du semantisch zusammengehörige Abläufe in der
Applikation gruppieren möchtest.

Es steht dir frei, ob du das im StreetsController machst oder einen
für die Suche anlegst. Das kommt ganz auf deine Applikation an. Ein
eigener Controller ist sicherlich sinnvoll, wenn etwas nicht eindeutig
zum einen oder anderen Controller gehört.

Grüße,
Timo


--
Timo Derstappen

http://teemow.com
mailto:tee...@gmail.com

Andreas

unread,
May 20, 2007, 10:40:42 AM5/20/07
to CakePHP-de für deutsche CakePHP Entwickler
Vielen Dank für eure Antworten.

Das mit $uses war genau der Hinweis den ich brauchte. Danke auch für
die zusätzichen Hinweise zu den Model-Relationen und den Cake-Plural-
Konventionen ;-)

Ich werde es jetzt wohl mal mit einem SearchesController versuchen -
da ich diese Suche weder dem einen noch dem anderen Controller
eindeutig zuordnen kann.

Gruß
Andreas

Schwarz Kathrin

unread,
May 25, 2007, 4:05:28 AM5/25/07
to CakePHP-de für deutsche CakePHP Entwickler
Ich habe die Variante eines searches_controller gewählt und es klappt
sehr gut.
Um die Suche schneller zu machen habe ich folgende Möglichkeit genutzt
http://www.mysql.org/doc/refman/5.0/en/fulltext-search.html
mit crate index ind_id ----- etc.

Grüße
Kathrin

Reply all
Reply to author
Forward
0 new messages