简体   繁体   中英

Yii many to many, junction table object graph

I am taking a Java app and moving it to php. I am experienced in java and used hibernate for the ORM solution. I have an existing data model to use and am implementing it in Yii.

I need help.

I have many-to-many relationships.

diet -> dietmeal <- meal -> mealfood <- food

junction tables are : dietmeal mealfood

A diet can have many meals & meals can belong to many diets. A meal can have many foods & foods can belong to many meals.

The Junction tables have fields I need to use in my view and also update. For example: quantity, unit_of_measure. How can I get these fields all at once, hence loading both the junction table main tables?

In Java Hibernate it's quite easy.

The sql I want to generate with yii is the following, also having yii populate the entire object graph, Populate the diet -> dietmeal <- meal -> mealfood <- food

Here is an example of the Output from Hibernate. It executes this sql and fills the object graph.

select distinct diet.*[columns] ,
dietmeal.*[columns],
meals.*[columns],
mealfood.*[columns],
foods.*[columns],
childfoods.*
from test_schema.diet diet
left outer join test_schema.diet_meal dietmeal on diet.id=dietmeal.diet_id
left outer join test_schema.meal meal on dietmeal.meal_id=meals.id
left outer join test_schema.meal_food mealfood on meals.id=mealfood3_.meal_id
left outer join test_schema.food foods on mealfood.food_id=foods.id
left outer join test_schema.food childfoods on foods.id=childfoods.parent_id
left outer join test_schema.schedulable schedulabl on diet.schedulable_id=schedulabl6_.ID
where diet.id=19
order by dietmeal.time asc,
meals.name desc,
foods.calories desc

How can I pull this off in yii? How do I set it up, so I can execute a join like this and get the entire object graph filled.

How to do in Yiii 1.* and 2.*

You need to go back to the basics of Yii and its ActiveRecord data modelling.

First off, you will need to define model classes for every database table. Each class has a relations function that you can overwrite to specify the relationships between tables.

class Diet extends CActiveRecord
{
   //      ...
    public function relations()
    {
        return array(
             // Take note of the relationship tag. We will see it later
             'meals'=>array(self::HAS_MANY, 'Dietmeal', 'diet_id'),
        );
    }
}

Note that you will also need to define the relationship in the Dietmeal class as well.

class Dietmeal extends CActiveRecord
{
   //      ...
    public function relations()
    {
        return array(
             'diet'=>array(self::HAS_MANY, 'Diet', 'diet_id'),
        );
    }
}

You are then able to structure your results

$dietModel = Diet::model()->findByPk(10);
// the 'meal' attribute is injected from the relationship name.
$dietMeals = $dietModel->meals;

References

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM