ugrás a tartalomhoz

Yii framework - relations probléma

react · 2011. Jún. 19. (V), 14.47
Yii-ben kezdtem fejleszteni, de elakadtam a relationök megadásánál. Keresgéltem és a tutorialokat is megnéztem, de nem találtam olyat, ahol világosan és részletesen le lenne írva, hogyan kell megadni a relatinöket.
Arról van szó, hogy van egy 'meal' tálba, ami a napi étkezések időpontját rögzíti, pl 12:00-kor volt egy étkezés, ehhez kapcsolódik a 'mealItem' tábla, ami az étkezésen belüli tételeket rögzíti és azok mennyiségét, pl egy tétel 100g vmilyen étel, egy másik tétel 50g másik étel, stb, ehhez a mealItem táblához kapcsolódik a 'food' tábla, ami az ételek adatait tartalmazza, tehát neve, zsírtartalom, stb.
Addig működik a dolog, hogy a Meal modellben relations() alatt megadom, hogy
  1. return array(  
  2.             'user' => array(self::BELONGS_TO, 'User''userId'),  
  3.             'foods' => array(self::MANY_MANY, 'Food''mealItem(mealId, foodId)'),  
  4.         );  
így a Meal modellbe szépen be is húzza az étel nevét és adatait, viszont a mennyiség (hogy hány grammot fogyasztott) az a köztes mealItem táblában található, ezt hogyan tudom lekérdezni?
Ezt a relationt a Gii adta meg automatikusan a mysql commentben jelzett foreign key-ek alapján.
További problémám a yii-vel, hogy a tutorialok közül szinte egyik sem működött hibátlanul, pl a blog tut is hibás, kiakad, és a weblaboron és másutt is közzétett Wiki tutorial se működik (a bejegyzések verziókövetése nem stimmel), így elég nehézkesen haladok vele sajnos.

A mysql táblák:
  1. CREATE TABLE `meal` (  
  2.   `id` int(11) NOT NULL AUTO_INCREMENT,  
  3.   `hourint(11) DEFAULT NULL,  
  4.   `minuteint(11) DEFAULT NULL,  
  5.   `userId` int(11) DEFAULT NULL COMMENT 'CONSTRAINT FOREIGN KEY (userId) REFERENCES user(id)',  
  6.   `datedate DEFAULT NULL,  
  7.   PRIMARY KEY (`id`),  
  8.   UNIQUE KEY `ora` (`hour`,`minute`,`userId`,`date`) USING BTREE  
  9. ) ENGINE=MyISAM AUTO_INCREMENT=507 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci  
  10. ;  
  11.   
  12. CREATE TABLE `mealItem` (  
  13.   `mealId` int(11) NOT NULL DEFAULT '0' COMMENT 'CONSTRAINT FOREIGN KEY (mealId) REFERENCES meal(id)',  
  14.   `foodId` int(11) NOT NULL DEFAULT '0' COMMENT 'CONSTRAINT FOREIGN KEY (foodId) REFERENCES food(id)',  
  15.   `quantity` float(11,0) DEFAULT NULL,  
  16.   PRIMARY KEY (`mealId`,`foodId`)  
  17. ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci  
  18. ;  
  19.   
  20. CREATE TABLE `food` (  
  21.   `id` int(11) NOT NULL AUTO_INCREMENT,  
  22.   `namevarchar(255) CHARACTER SET utf8 COLLATE utf8_hungarian_ci DEFAULT NULL,  
  23.   `energy` float DEFAULT NULL,  
  24.   `calorie` float DEFAULT NULL,  
  25.   `protein` float DEFAULT NULL,  
  26.   `fat` float DEFAULT NULL,  
  27.   `carb` float DEFAULT NULL,  
  28.   `fiber` float DEFAULT NULL,  
  29.   `usage` int(11) NOT NULL DEFAULT '0',  
  30.   PRIMARY KEY (`id`),  
  31.   KEY `name` (`name`)  
  32. ) ENGINE=MyISAM AUTO_INCREMENT=498 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci  
  33. ;  
 
1

Töröld a Gii által generált

phtamas · 2011. Jún. 19. (V), 19.45
Töröld a Gii által generált "foods" relációt, és definiáld a relációkat az alábbiak szerint:

Meal HAS_MANY MealItem
MealItem BELONGS_TO Meal
Food HAS_MANY MealItem
MealItem BELONGS_TO Food
Meal HAS_MANY Food through MealItem
Így a Meal model hozzáfér a köztes táblához is.

Ha dolgoztál már MVC keretrendszerrel, akkor a tutorialokat szerintem felejtsd el. A fentebb linkelt guideban le vannak írva az alapok, és nagyon jó, részletes API dokumentáció is van.
A Yii fórumát is érdemes használni, ha valami alapvető dologgal van problémád, akkor valószínűleg nagyon hamar választ kapsz.
2

köszönöm

react · 2011. Jún. 19. (V), 20.11
Köszönöm a gyors segítséget és a linkeket is!
Még annyit kérdeznék ha lehet, hogy a _view.php alatt $data->foods -ba miért csak a food mezői kerülnek bele, ha a mealItem-en keresztül van joinolva, miként adhatom meg relations() alatt, hogy a mealItem quantity mezője is belekerüljön a foodba (mivel a mennyiség tul.képpen a mealhez tartozik).
  1. public function relations()  
  2.     {         
  3.         return array(  
  4.             'user' => array(self::BELONGS_TO, 'User''userId'),  
  5.             'items' => array(self::HAS_MANY, 'MealItem''mealId'),  
  6.             'foods' => array(self::HAS_MANY, 'Food''foodId''through' => 'items'),  
  7.         );  
  8.     }  
_view.php alatt:
  1. <? foreach ($data->foods as $food) { ?>  
  2.     <b><?php echo CHtml::encode($food->getAttributeLabel('name')); ?>:</b>  
  3.     <?php echo CHtml::encode($food->name); ?>  
  4.     <br />      
  5. <? } ?>  
ugyanez quantity-vel már nem működik, mivel az mealItem táblában van, holott az is benne van a joinban a through miatt. Külön az items-en foreachelve el tudom érni, de közvetlenül a foods-on keresztül nem.
3

Erre sajnos nincs egyszerű és

phtamas · 2011. Jún. 19. (V), 21.06
Erre sajnos nincs egyszerű és elegáns megoldás, mert szigorú 1:1 hozzárendelés van a model objektumok és az adatbázis táblák között. Valami ilyesmivel érdemes próbálkozni:
  1. $meal = Meals::model()->findByPk($idarray(  
  2.     'with' => array(  
  3.         'foods',  
  4.         'items' => array('index' => 'foodId'),  
  5.     ),  
  6. ));  
  7. foreach ($meal->foods as $food) {  
  8.     $quantity = $meal->items[$food->id]->quantity;  
  9. }