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

return array(
			'user' => array(self::BELONGS_TO, 'User', 'userId'),
			'foods' => array(self::MANY_MANY, 'Food', 'mealItem(mealId, foodId)'),
		);
í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:

CREATE TABLE `meal` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `hour` int(11) DEFAULT NULL,
  `minute` int(11) DEFAULT NULL,
  `userId` int(11) DEFAULT NULL COMMENT 'CONSTRAINT FOREIGN KEY (userId) REFERENCES user(id)',
  `date` date DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `ora` (`hour`,`minute`,`userId`,`date`) USING BTREE
) ENGINE=MyISAM AUTO_INCREMENT=507 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
;

CREATE TABLE `mealItem` (
  `mealId` int(11) NOT NULL DEFAULT '0' COMMENT 'CONSTRAINT FOREIGN KEY (mealId) REFERENCES meal(id)',
  `foodId` int(11) NOT NULL DEFAULT '0' COMMENT 'CONSTRAINT FOREIGN KEY (foodId) REFERENCES food(id)',
  `quantity` float(11,0) DEFAULT NULL,
  PRIMARY KEY (`mealId`,`foodId`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
;

CREATE TABLE `food` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) CHARACTER SET utf8 COLLATE utf8_hungarian_ci DEFAULT NULL,
  `energy` float DEFAULT NULL,
  `calorie` float DEFAULT NULL,
  `protein` float DEFAULT NULL,
  `fat` float DEFAULT NULL,
  `carb` float DEFAULT NULL,
  `fiber` float DEFAULT NULL,
  `usage` int(11) NOT NULL DEFAULT '0',
  PRIMARY KEY (`id`),
  KEY `name` (`name`)
) ENGINE=MyISAM AUTO_INCREMENT=498 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
;
 
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).

public function relations()
	{		
		return array(
			'user' => array(self::BELONGS_TO, 'User', 'userId'),
			'items' => array(self::HAS_MANY, 'MealItem', 'mealId'),
			'foods' => array(self::HAS_MANY, 'Food', 'foodId', 'through' => 'items'),
		);
	}
_view.php alatt:

<? foreach ($data->foods as $food) { ?>
	<b><?php echo CHtml::encode($food->getAttributeLabel('name')); ?>:</b>
	<?php echo CHtml::encode($food->name); ?>
	<br />	
<? } ?>
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:

$meal = Meals::model()->findByPk($id, array(
    'with' => array(
        'foods',
        'items' => array('index' => 'foodId'),
    ),
));
foreach ($meal->foods as $food) {
    $quantity = $meal->items[$food->id]->quantity;
}