[solved] automatically eager load a model's relation on every find

Hello,

I am new to yii and still trying to get the hang of it

So far the framework looks impressive, the only thing I miss using it is having smarty around. I know template frameworks are excluded on purpose and smarty can be easily integrated, just saying.

on to the problem…

Almost all the applications I work on include content translated in more than one language, localization and sometimes internationalization is a necessity. I have seen & like the way yii handles page translations, but when it comes to multilanguage content I haven’t found a solid solution after looking around a bit.

Up to now the way we handle this is by having a tbl_content_l10n for each tbl_content holding all strings related to tbl_content items’ that ask for translation, and in the run time when loading a tbl_content model we automatically join the session language’s related strings.

As you can imagine eager loading is almost a must-have since almost everything we deal with is of this nature.

As of now the closest I have come to our original behaviour is using




$category = Category::model()->with(array(

		'products'=>array(),

		'l10n'=>array(

			'condition' => 'lang_id="' . $_SESSION['lang'] . '"',

			'limit'=>'1',

		),

	))->find();



But this returns an array in $category->l10n which I have to shift to get the single language loaded, or use $category->l10n[0] etc, which is not very handy.

I have thought of overriding findByPk and other find-related methods of CActiveRecord, but I suspect this wouldn’t be enough since I need this data loaded even when the model in question is loaded as a relation of another model…

any suggestions?




...

'l10n'=>array(

                        'condition' => 'lang_id=:lang_id',

                        'limit'=>'1',

                        'params'=>array(':lang_id'=>$_SESSION['lang'),     //'params'=>array(':lang_id'=>Yii::app()->user->lang,

            )

...



Also, You don’t need to use $_SESSION, you should do something like this somwhere in your code (maybe, after successfull authorization in site/login method):




Yii::app()->user->setState('lang','USER LANGUAGE');



After that you can write Yii::app()->user->lang everywhere in your code, in our example it returns string ‘USER LANGUAGE’.

Also,


 'limit'=>'1'

, will not help You - no matter - method with() will returns an array of related models, if relation is


self::HAS_MANY

, even when the one model will be returned - it will be returned as array with one element.

Define a new relation in Category model:




'localized' => array(

	self::HAS_ONE,

	'CategoryL10n', // replace it with the actual name of l10n-model class

	'category_id',

	'alias' => 'category_localized',

	'on' => 'category_localized.lang_id=' . $_SESSION['lang'],

),



Add it to default scope:




public function defaultScope()

{

	return array('with' => 'localized');

}



phtamas that’s exactly what I was looking for, many thanks