HAS_ONE problem

I have two tables:

company and company_descr

company

  • id

  • name

company_descr:

  • companyId

  • extraData

Model classes:


class Company extends CActiveRecord

{

   public function relations()

   {	

	return array(			

            'descr' => array(self::HAS_ONE, 'CompanyDescr', 'companyId')

		);	

   }

}




class CompanyDescr extends CActiveRecord

{

   public function relations()

   {	

	return array(			

            'company' => array(self::BELONGS_TO, 'Company', 'companyId')

		);	

   }

}

I want to get extraData field through Company model.

When I try




$model=new Company($id);

$model->descr->extraData;

I get error "Trying to get property of non-object"

I don’t understand what I am doing wrong.




$model= Company::model()->findByPk($id);

$model->descr->extraData;



Thank You! Now it works :)

May you explain this a little bit, I don’t understand (buuh, newbie, sorry!!!)

I have a similiar problem with Larry Ullmanns tutorial. I would like to add a relation according the departments head:

models/Department.php:


public function relations()

{

  return array(

    'head' => array(self::HAS_ONE, 'Employee', 'id')

  );

}

department/_view.php trying to traverse the relation:


<?php

  echo CHtml::encode($data->head->lastName);

?>

But it creates the error mentioned above

It works when directly accessing an attribute of the department like


<?php

  echo CHtml::encode($data->name); 

?>

This all is within a CListView widget, maybe this causes the problems???

According The Definitive Guide to Yii I have to loop through the results, but why (the relation is declared only as HAS_ONE) and how?

Thanks

Achim

For the data provider you use with CListView, you are probably using a $model->search();

Make sure the search function on your model does return the Data provider with your relation…

Check the example code for CActiveDataProvider… http://www.yiiframework.com/doc/api/1.1/CActiveDataProvider

Hmm, no, the data provider is configured to simply return all, see this sniplet in the DepartmentController.php


public function actionIndex()

{

  $dataProvider=new CActiveDataProvider('Department');

  $this->render('index',array(

    'dataProvider'=>$dataProvider,

  ));

}

Within the according view the dataProvider is only assigend, see department/index.php


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

        'dataProvider'=>$dataProvider,

        'itemView'=>'_view',

));

So there is nowhere a search() which could limit the result or cut of the relation data… :angry:

I extended the tutorial as a kind or exercise to understand the framework. This should be a preparation to be able to code own sites, but it looks like I didn’t got it…

Thanks anyhow

Achim

Aaaargh, i found it by some hint!

I had some “holes” in my data, some department records didn’t had the heads-id set. For these records the relation form Department to Employee was not defined. So I did:


if (!empty($data->head))

  echo CHtml::encode($data->head->lastName);

else

  echo 'n.n.';

A typical runtime error, nothing to do with Yii. Now it works like a charm!!!

thanks a lot

Achim

Try this




public function actionIndex()

{

  $dataProvider=new CActiveDataProvider('Department',array(

    'criteria'=>array(

        'with'=>array('head'),

    ));


  $this->render('index',array(

    'dataProvider'=>$dataProvider,

  ));

}



// remember that if there is no related object it will fail too…

Hmm, what’s the benefit of this criteria-lines?

I can access the records behind “head” also without these lines and it don’t solve the no-object problem?!?!

You are using lazy loading, whilst the other uses eager loading. The no-object problem is the same if there is no relation… I guess is whatever you wish to use…