Reputation: 7019
As you would guess from the two snips below, I will reference the Category table when displaying Part details.
public function relations() {
return array(
'category' => array(self::BELONGS_TO, 'Category', 'fid_caty2') );
}
public function relations() {
return array('part' => array(self::HAS_MANY, 'Part', 'fid_caty2') );
}
I've learned this method of rendering the referenced value in a view:
echo CHtml::encode($data->category->name_caty2);
I've found some other methods too, but they all take place in the view. Since the model sets the relationship, why shouldn't the referenced value be included in the CActiveRecord
of the model? I thought this was exactly the kind of crunching we reserved for the model. Working it out in a view seems strange, plus a lot of extra work.
If I'm right, how do I make it work in the model view? Or does my understanding of MVC need correction?
public function loadModel($id)
{ $model=Part::model()->findByPk($id);
if($model===null)
throw new CHttpException(404,'The requested page does not exist.');
return $model;
}
Here are in the controller page. Can I sneak my referenced value into the model when it is loaded?
Upvotes: 0
Views: 148
Reputation: 4150
Yii uses lazy loading, which means it only loads the models it needs, and therefore only queries the tables it needs for a set statement.
When you pull your Part model in your controller, for example;
$data = Part::model()->findAll($criteria);
You won't be pulling the relation, as it's not explicitly needed, and as you've already mentioned, your code in the view;
$data->category->name_caty2;
Will perform another query, and you don't want to do that in the view, you're right in your question that business logic shouldn't appear in the view.
The way around this is to use Yii's eager loading (as opposed to lazy loading mentioned above). As mentioned in the manual;
The eager loading approach retrieves the related AR instances together with the main AR instance(s). This is accomplished by using the with() method together with one of the find or findAll methods in AR. For example,
$posts=Post::model()->with('author')->findAll();
So in your case, you would need to use;
$data = Part::model()->with('category')->findAll($criteria);
Upvotes: 2