[SOLVED] Nested Foreign Key Relations

Hi All,

I have an Action model. Each Action belongs to a Person and an ActionCategory. The relations for these are defined as follows:

models/ActionCategories.php:




class ActionCategories extends CActiveRecord

{

.......

  public function relations()

  {

    // NOTE: you may need to adjust the relation name ann the related

    // class name for the relations automatically generated below.

    return array(

      'actionsRel' => array(self::HAS_MANY, 'Actions', 'category'),

    );

  }



models/Actions.php:




class Actions extends CActiveRecord

{

.......

  public function relations()

  {

    // NOTE: you may need to adjust the relation name and the related

    // class name for the relations automatically generated below.

    return array(

      'actionCategoryRel' => array(self::BELONGS_TO, 'ActionCategory', 'id'),

      'actionAssignedToRel' => array(self::BELONGS_TO, 'Person', 'id', 'together' => true),

    );

  }



models/Person.php:




class Person extends CActiveRecord

{

.......

  public function relations()

  {

    // NOTE: you may need to adjust the relation name and the related

    // class name for the relations automatically generated below.

    return array(

      'actionsRel' => array(self::HAS_MANY, 'Actions', 'assigned_to'),

    );

  }



I want to use a CListView, so in my controller I instantiate a CActiveDataProvider and pass it to my view:




  $dataProvider = new CActiveDataProvider(ActionCategory::model()->with('actionsRel'));

  $this->render('index', array('actionCategories' => $dataProvider));



Finally, my view uses a CListView as follows:




 $this->widget('zii.widgets.CListView', array(

   'dataProvider'=>$actionCategories,

   'itemView'=>'_actionsView',   // refers to the partial view named '_actionsView.php'

   'sortableAttributes'=>array(

     'name',

     'id',

   ),

 ));



My partial view (_actionsView.php) can access




$data->actionRel 



to obtain a list of Actions for each ActionCategory. However, I am unable to link each action to a person. That is, I cannot access




$data->actionRel[$i]->actionAssignedToRel->firstname 



Please help. Thanks.

Always use the foreign key column name in relation definition, not the primary key of the related table.

Thanks for picking that up phtamas. I have changed my relations for my Actions model to:




  public function relations()

  {

    // NOTE: you may need to adjust the relation name and the related

    // class name for the relations automatically generated below.

    return array(

      'actionCategoryRel' => array(self::BELONGS_TO, 'ActionCategory', 'category'),

      'actionAssignedToRel' => array(self::BELONGS_TO, 'Person', 'assigned_to'),

    );

  }



but I still can’t access $data->actionsRel->actionAssignedToRel. Do I need to include a ->with(‘actionAssignedToRel’) somewhere?

Any help appreciated.

What does it actually mean? Do you get an error? Or just a NULL value as result?

It would be a good idea for performance reasons, but not strictly required to make your code work.

I found what I was looking for here: http://www.yiiframework.com/doc/guide/1.1/en/database.arr :). In short, I was trying to achieve the following output in my view:




ActionCategory 1

  action 1 - Person A

  action 2 - Person B

  action 3 - Person A

  action 4 - Person F


ActionCategory 2

  action 1 - Person F

  action 2 - Person A

  action 3 - Person A



I needed to add my ‘actionAssignedToRel’ relationship to the ‘with’ call as follows:




$dataProvider = new CActiveDataProvider(ActionCategory::model()->with('actionsRel.actionAssignedToRel'));



You have just about answered my question, but stopped short. I’ve got something similar to you, but can’t work out what code to use to iterate through the related results (in your case Actions) under each Category.

In the same way I can print_r the array contents of $data->actionRel in the partial view, but what code is used to print out each of the instances of Action in that view?

Thanks

got it… use a loop. Duh.

thanks