Using Relation In Afterfind

I got a User model, with 7 records in it.


public function afterFind()

{

     parent::afterFind();

     $this->thumb = $this->mainPhoto->file;


}


public function getMainPhoto()

{

     return $this->hasOne(Photo::className(), ['userId' => 'id'])->onCondition('photoType = 1');

}




User::find()->with('getMainPhoto')->all();

When i use this without the $this->thumb … line in my afterFind() method, the correct amount of queries are executed, including this one:


SELECT * FROM `photo` WHERE (`userId` IN ('62', '61', '60', '58', '56', '55', '54')) AND (photoType = 1)

When i add the $this->thumb … line in my afterFind() method, there are 7 more queries (one for each row) executed:


SELECT * FROM `photo` WHERE (`userId` IN ('62', '61', '60', '58', '56', '55', '54')) AND (photoType = 1)

SELECT * FROM `photo` WHERE (`userId`='54') AND (photoType = 1)

SELECT * FROM `photo` WHERE (`userId`='55') AND (photoType = 1)

SELECT * FROM `photo` WHERE (`userId`='56') AND (photoType = 1)

and so on..

That doesn’t seem right i think? It doesn’t recognize that ‘with’ is used here, so it uses lazy loading to load each photo.

Edit:

I want to use this approach because i need to do some extra stuff with the thumb here (show a different picture when mainPhoto->file is empty).

Nice question.

I think the quick fix for you would be using a getter:


public function getThumb()

{

    return isset($this->mainPhoto) && is_file('/path/to/image/' . $this->mainPhoto->file) ? $this->mainPhoto->file : 'defaults here';

}

and then somewhere in a view:


<img src="<?= $item->thumb ?>" />

The interesting part though is sudden lazy loading. I suppose that model’s relations are set after afterFind() or something alike.

Yes i also think the relations are set after afterFind(), if i’m right, this worked correct in Yii 1.x though.

But your solution is very nice, i will use it, thanks!

Seems like this issue has just been fixed.

Very nice! Thanks! :) it works correctly now.

For some reason, this problem is back again since the last update (?). I’m making the join in a scope, placed in xxxxQuery extends ActiveQuery. When i’m using the relation in afterFind() an extra query for the relation is executed (and the join is made as well).


SELECT `user`.* FROM `user` LEFT JOIN `photo` ON (`user`.`id` = `photo`.`userId`) AND (photoType = 1) WHERE (accountStatus = 1 AND accountType <> 3) AND (`user`.`id`='62')

Caused by this line in my afterFind method:


$this->thumb = isset($this->mainPhoto) ? $this->mainPhoto->file : Yii::$app->params['noPicUrl'];


SELECT * FROM `photo` WHERE (`userId`='62') AND (photoType = 1)

Report an issue.

Yes, just did: https://github.com/yiisoft/yii2/issues/2108