best practice when working with has_many and many_many relationship

Hi everyone,

I’m wondering what would be considered best pratice when working with has_many and many_many relationships in the following situation:

Suppose I have a many_many relationship between Post and Category.

In the update dialog for my post model I’d then have a CHtml::activeCheckBoxList where the user can check the categories a post belongs to.

I have the following questions about this.


[*]The activeCheckBoxList obviously needs to know what categories are available. Shall I fetch those in the controller and pass them on to the view using the data array in the CController::render method and then do something like this:

CHtml::activeCheckBoxList($model, 'category_ids',$groups, 'id', 'name') )

or shall I fetch that data inside the model like this:

CHtml::activeCheckBoxList($model, 'category_ids',CHtml::listData(Category::model()->findAll(), 'id', 'name') )

The same obivously applies to has_many relationships.

[*]What should the name of the activeCheckBoxList be? Currently I’ve created a public category_ids attribute in my Post class which I then process in the afterSave() method to populate the join table. Is this the way it’s supposed to be done or is there a better way? Something tells me there is :)


Hi MarcS,

I’m far from being an expert, but here is my opinion.

  1. To my mind, a view should have a minimum of server code. So, views should have minimum of processing and a maximum of variables. I would choose this way

CHtml::activeCheckBoxList($model, 'category_ids',$groups, 'id', 'name') )

  1. Well, this way is a very simple way. You need to save the post before linking it to its categories. So, doing it on [font="Courier New"]afterSave[/font] is correct. What kind of options are you waiting for?

Don’t forget, I’m far from being an expert.

I was hoping that there’d by another way to do this which wouldn’t require me to manually populate the category_ids array so that the selected options get checked.

I made a change to CHtml that allows this, but as I am new to Yii I don’t know if this follows the “best practices”.

	public static function activeCheckBoxList($model,$attribute,$data,$htmlOptions=array())



		if(is_array($model->$attribute) && isset($htmlOptions['attributeitem']) && $htmlOptions['attributeitem'])



			foreach ($model->$attribute as $a)


		} else






		return self::hiddenField($name,'',array('id'=>self::ID_PREFIX.$htmlOptions['id']))

			. self::checkBoxList($name,$selection,$data,$htmlOptions);


echo $form->checkBoxList($model,'operations',CHtml::listData(WOBJOperation::model()->findAll(array('order'=>'ds_operation_ope')), 'cd_operation_ope', 'ds_operation_ope'), array('attributeitem'=>'cd_operation_ope'));