Eager Loading in 1.1.x

Hi team,

It’s been a while since I have used yii and I am having some issues upgrading my old applications to yii 1.1.2.

The issue I am having is when using eager loading, for example;

I am loading a record like this;

$criteria=new CDbCriteria;

        $criteria->condition = 't.is_active=1 AND e.is_primary=1';

        $success = PUser::model()->with('emails')->findByAttributes(array('nonce'=>$_GET['t']), $criteria);

        $email = $success=>emails->email;

I get this error;

PHP Error


Trying to get property of non-object

Source File



00245:     /**

00246:      * Reset a user password.

00247:      */

00248:     public function actionReset()

00249:     {

00256:         $email = $success->emails->email;

Please advise what I am doing wrong.

I simply want to get the user email address and store it, as I use this later in my behaviour.




anyone got a tip.

Either $success is empty (findByAttributes didn’t find anything) or $succcess->emails is empty (no related emails). So check those values to debug:

if ($success===null)

  die('success is empty');

elseif ($success->emails===null)

  die('success->emails is empty');

Also enable CWebLogRoute + param logging to check your queries.

[s]Oh, and findByAttributes doesn’t expect a CDbCriteria as second argument. So you should rewrite that to something like:

$criteria=new CDbCriteria;

$criteria->condition = 't.is_active=1 AND e.is_primary=1 AND nonce=:nonce';


$success = PUser::model()->with('emails')->find($criteria);


Forget that - it can be a criteria :)

I enabled CWebLogRoute and param logging;

$success shouldn’t be empty. Here is the sql when queried;

SELECT `t`.`id` AS `t0_c0`, `t`.`is_active` AS `t0_c1`,

`t`.`role_id` AS `t0_c2`, `t`.`password` AS `t0_c3`, `t`.`nonce` AS

`t0_c4`, `t`.`last_visit` AS `t0_c5`, `t`.`is_super_admin` AS `t0_c6`,

`t`.`expire_at` AS `t0_c7`, `t`.`created_at` AS `t0_c8`, `t`.`updated_at`

AS `t0_c9`, `t`.`created_by` AS `t0_c10`, `t`.`updated_by` AS `t0_c11`,

`e`.`user_id` AS `t1_c0`, `e`.`email` AS `t1_c1`, `e`.`label` AS `t1_c2`,

`e`.`is_primary` AS `t1_c3`, `e`.`is_active` AS `t1_c4`, `e`.`nonce` AS

`t1_c5`, `e`.`expire_at` AS `t1_c6`, `e`.`created_at` AS `t1_c7`,

`e`.`updated_at` AS `t1_c8`, `e`.`created_by` AS `t1_c9`, `e`.`updated_by`

AS `t1_c10` FROM `User` `t`  LEFT OUTER JOIN `Email` `e` ON

(`e`.`user_id`=`t`.`id`) WHERE (`t`.`nonce`=:yp0 AND (t.is_active=1 AND

e.is_primary=1)). Bind with parameter :yp0='qveq5fu6cv5p'

When copied into phpmyadmin and replacing :ypo with parameter;

t0_c0	t0_c1	t0_c2	t0_c3	t0_c4	t0_c5	t0_c6	t0_c7	t0_c8	t0_c9	t0_c10	t0_c11	t1_c0	t1_c1	t1_c2	t1_c3	t1_c4	t1_c5	t1_c6	t1_c7	t1_c8	t1_c9	t1_c10

53	1	1	a750680f04a89838a4af45310c5360970e08b325	qveq5fu6cv5p	1277874243	0	1278227250	1277874243	1277881650	0	0	53	test@test.com	NULL	1	1	jtotzov7nb2g	1278219843	1277874243	1277874262	0	0

t1_c1 being column ‘email’

Why is it not parsing the information

Is it because both tables have columns of the same name? Would that be throwing a spanner in the works?

Trying to get property of non-object


Stack trace:

#0 C:\wamp\www\Yii\framework\web\filters\CFilterChain.php(129):


#1 C:\wamp\www\Yii\framework\web\filters\CFilter.php(41):


#2 C:\wamp\www\Yii\framework\web\CController.php(999):


#3 C:\wamp\www\Yii\framework\web\filters\CInlineFilter.php(59):


#4 C:\wamp\www\Yii\framework\web\filters\CFilterChain.php(126):


#5 C:\wamp\www\Yii\framework\web\CController.php(283): CFilterChain->run()

#6 C:\wamp\www\Yii\framework\web\CController.php(257):


#7 C:\wamp\www\Yii\framework\web\CWebApplication.php(320):


#8 C:\wamp\www\Yii\framework\web\CWebApplication.php(120):


#9 C:\wamp\www\Yii\framework\base\CApplication.php(135):


#10 C:\wamp\www\test\index.php(12): CWebApplication->run()


in C:\wamp\www\test\protected\controllers\AccountController.php (256)

in C:\wamp\www\test\index.php (12)

Is emails a HAS_MANY relation in user? If so, $success->emails would be an array. And again: what exactly is empty? $success or $success->emails?

emails is a HAS_MANY relation in PUser model.

So yes, $success->emails is an array

I did your debug and no errors, so neither is empty.

All I am trying to do is join two tables;



I then want to filter results by $_GET[‘t’] value which is represented in PUser model by column ‘nonce’

Now that results are filtered I want to get the users email address which is stored in Model PEmail.

In previous version of yii, I just would have done;


So, as the error states, you try to access a property of a non object: $success->emails is an array, that has no properties. You should fetch the first entry from that array to get your desired record. Quick way to make this safe:

$email=isset($success->emails[0]) ? $success->emails[0]->email : '';

Thanks for all your help mike.

I thought the idea of using a ‘with’ statement in active record simplified and made it easy to be able to work with the joined data.

Can someone show me script on how they grab a column data from a joined table using active record. I swear I used to be able to do this in yii 1.0.


I fixed this by changing the models around;

$criteria=new CDbCriteria;

		$criteria->condition = 'u.is_active=1 AND t.is_primary=1 AND u.nonce=:nonce';


		$success = PEmail::model()->with('user')->find($criteria);

As a result the relation was HAS_ONE

Per definition a HAS_MANY relation has many related objects. An Array is already the easiest representation of such a list. If that’s still too complicated, you can define another relation for the primary email to the same table:

public function relations() {

    return array(


            'condition'=>'primary_email.id_active=1 AND e.is_primary=1',





Thanks Mike… That makes perfect sense to me now. I didn’t think to do that, cheers for your explanation