Adatok optimális lekérdezése: bindModel(), unbindModel()

A cakephp biztosí­tja számunkra azt a fantasztikus lehetőséget, hogy modelekben egyszerűen adhatjuk meg a táblák közötti kapcsolatokat, a többit a rendszer elintézi nekünk. Nagyobb projekteknél azonban könnyen előfordulhat, hogy túlságosan is a “fejünkre nő” ez a funkció, sok felesleges adatot kérdezünk le. Erre gyógyí­r a cí­mbeli két függvény.

Tegyük fel, hogy túlléptünk már a Post, Comment, Tag bemutató hármas bonyolultságán. Vegyünk egy egyszerű (részleges) példát. Embereket (Person) tartunk nyilván, jelölve, hogy melyik városban (City) élnek, a városokat pedig megyékbe (County) soroljuk. Szeretnénk lekérdezni az összes emberünket és kií­ratni őket egy egyszerű listában: Név (Város / Megye). Mi sem egyszerűbb

$this->Person->recursive = 2;
$people = $this->Person->findAll();

(egyszerűbb előbb beállí­tani a lekérdezés mélységét (recursive) közvetlenül, ugyanis minden find() függvényben sajnos ez csak az utolsó paraméter; és kinek van kedve annyi null-t í­rni🙂 )
Ezzel készen is vagyunk. Gondolnánk. Nézzünk most egy debug($people); -t. Azt látjuk, hogy minden város alatt nem csak a hozzá tartozó megyék jelennek meg, hanem a városhoz rendelt összes ember is. Hoppá. Ezt 5-6 ember esetén nem jelent nagyobb problémát, de 10ezer esetén már igen. Akkor szabaduljunk meg a felesleges ember listától:

$this->Person->City->unbindModel(array('hasMany'=>array('Person')));
$this->Person->recursive = 2;
$people = $this->Person->findAll();

Na itt álljunk meg egy pillanatra. Több dolog is szemet szúrhat.
1. nem használjuk a $uses = array(‘Person’, ‘City’); paramétert, ugyanis a City kapcsolatban van a Person modellel, ezért azon keresztül (láncban) elérhető. Egy gonddal kevesebb.
2. az unbindModel() paramétere egy asszociatí­v tömb, ahol a kulcsok a kapcsolat tí­pusai lehetnek: belongsTo, hasOne, hasMany, hasAndBelongsToMany (példánkban hasMany). Minden kulcshoz hozzá van rendelve egy tömb, amelyben a megszüntetni kí­vánt kapcsolat nevét kell megadni.
3. a manualban le van í­rva, de inkább kétszer, mint egyszer se: az bindModel() és az unbindModel() csak az azt követő lekérdezésre van hatással, a következőkre már nem.

Folytassuk a példát: tegyük fel, hogy az emberek képet (Image) is feltölthetnek magukról a rendszerbe (akár többet is, tehát ez egy hasMany kapcsolat). A listánkban azonban csak egy képet szeretnénk megjelení­teni. A fenti lekérdezés után viszont ugyanazt tapasztaljuk a képek vonatkozásában, mint korábban a városok vonatkozásában. Nem baj, erre már tudjuk a megoldást:

$this->Person->Image->unbindModel(
  array('belongsTo'=>array('Person'))
);

Ezzel megszüntettük a felesleges adat lekérést, de továbbra is megkapjuk az összes képet. Itt jelenik meg a szinen a bindModel().

$this->Person->bindModel(
  array('hasMany'=>array('Image'=>array('limit'=>1)))
);

Majdnem ugyanazt látjuk, mint az unbindModel() esetében, csak itt annyival megyünk túl, hogy a kapcsolat nevéhez is rendelük egy tömböt (mint a model leí­rása folyamán), amelyben megadjuk a paraméterfeltételeket paraméter (kulcs) és feltétel (érték) párokkal.

Tehát még egyszer az egész példa:

$this->Person->City->unbindModel(
  array('hasMany'=>array('Person'))
);
$this->Person->Image->unbindModel(
  array('belongsTo'=>array('Person'))
);
$this->Person->bindModel(
  array('hasMany'=>array('Image'=>array('limit'=>1)))
);
$this->Person->recursive = 2;
$people = $this->Person->findAll();

Ennyit mára. Egészségetekre.

Kategória: cakephp
Címke: , ,
Közvetlen link a könyvjelzőhöz.

Vélemény, hozzászólás?

Adatok megadása vagy bejelentkezés valamelyik ikonnal:

WordPress.com Logo

Hozzászólhat a WordPress.com felhasználói fiók használatával. Kilépés / Módosítás )

Twitter kép

Hozzászólhat a Twitter felhasználói fiók használatával. Kilépés / Módosítás )

Facebook kép

Hozzászólhat a Facebook felhasználói fiók használatával. Kilépés / Módosítás )

Google+ kép

Hozzászólhat a Google+ felhasználói fiók használatával. Kilépés / Módosítás )

Kapcsolódás: %s