Best Practices for a controller with multiple models

I have three tables: I have an employee table that has fields like: id (PK), full_name, etc. I have a table of projects, with fields like: id (PK), project_name. I have a third table that will be a combination of the two with foreign keys: id (PK), employee_id (FK), project_id (FK). This seemed the best way to do a Many:Many relationship, so to notate an employee is working on a project, we make a record in this third table keyed to the other two.

So now I’m making my form work to enter or edit an employee and mark what projects they’re working on. I autogenerated (gii) the form for the employee controller/view so just that works great to create/edit and save an employee. I then modified my view to include checkboxes reading from my project table

echo CHtml::activeCheckboxList(

$model, ‘id’,

CHtml::listData(projects::model()->findAll(array(‘order’=>‘project_name’)), ‘id’, ‘project’),

array(‘separator’=>’ ‘,‘template’=>’<div class=“my_checkboxes”>{input} {label}</div>’,)

);

So this works pretty well to display the names of the projects, but I’m kinda stuck on how to actually work with it. I think “$model” is wrong in this context because that’s the employee model since I’m in the _form table for that view.

My question is how to properly set this up especially when it comes to the actionUpdate() in my employee controller, since I have to get whatever rows exist in my third table and pass those to the checkboxes so they’re properly checked.

It was quite a revelation to me to learn I didn’t need a controller for every model. Here is what I do in my project.

I have a similar situation with templates and criteria (many_many relationship). So I have a template controller and a criteria controller, along with models for template, criteria, and templateCriteria.

The template controller and view displays all the options in the criteria table. I use a multiselect widget instead of checkboxes but its the same idea from the controller perspective.

Some code:




	public function actionCreate()

	{

		$model=new Template;


		if(isset($_POST['Template']))

		{

			$model->attributes=$_POST['Template'];

			if($model->save()) {	

				if(isset($_POST['Template']['criterias'])) {

					foreach ($_POST['Template']['criterias'] as $criteri) {

						//Foreach criteria posted to template, load TemplateCriteria model

						//and assign templateId and criteriaId, save it.

						$TemplateCriteria = new TemplateCriteria;

						$TemplateCriteria->templateId = $model->id;

						$TemplateCriteria->criteriaId = $criteri;

						$TemplateCriteria->save();

					}

				}

				//Set create flash message and send user to manage templates page

				Yii::app()->user->setFlash('success', "Template '$model->templateName' created successfully.");

				$this->redirect(array('index'));

			}

		}


		$this->render('create',array(

			'model'=>$model,

		));

	}



FYI

There are a few extensions for saving many-many related records. You’ll notice I am not using them in this example. It was really important to understand how to work with related data with Yii - so learn that first and then install an extension for convenience later.