I’m either doing this wrong or I’m missing something. I have a Company model with an additional property defined called $companyEmployees. This property accepts an array coming from a multiple SELECT element and uses that to populate a related model called CompanyEmployee (which itself is related to an Employee model so its basically a MANY_MANY setup). Create and update code work fine but when I’m updating and want to deselect every employee, it should remove all employees from the CompanyEmployee model but that doesn’t happen because my $companyEmployees attribute keeps its loaded values (since the select element has nothing selected, it doesn’t pass any POST data to overwrite my custom attribute). Here’s how my setup basically looks like:
Company.php
public $assignedEmployees;
public function relations()
{
public function relations()
{
return array(
'assignedEmployees' => array(self::MANY_MANY, 'Employee', 'company_employee(company_id, employee_id)'),
'companyEmployees' => array(self::HAS_MANY, 'CompanyEmployee', 'company_id'),
);
}
public function afterFind()
{
$this->assignedEmployees = CHtml::listData($this->assignedEmployeeAccounts, 'id', 'id');
parent::afterFind();
}
}
CompanyController.php
public function actionUpdate($id)
{
$model = $this->loadModel($id);
if (isset($_POST['Company']))
{
$model->attributes = $_POST['Company'];
if ($model->save())
{
// Remove any assigned employees not found.
foreach ($model->companyEmployees as $companyEmployee)
{
if (!in_array($companyEmployee->employee_id, $model->assignedEmployees))
{
$companyEmployee->delete();
}
else
{
// Unset found entries by searching for the right key using value. This leaves the array with newly selected entries
if (($key = array_search($companyEmployee->employee_id, $model->assignedEmployees)) !== false)
{
unset($model->assignedEmployees[$key]);
}
}
}
// Insert any remaining, new employees from the array
foreach ($model->assignedEmployees as $employeeId)
{
$companyEmployee = new CompanyEmployee;
$companyEmployee->attributes = array(
'company_id' => $model->id,
'employee_id' => $employeeId,
);
$companyEmployee->save();
}
$this->redirect(array('view', 'id' => $model->id));
}
}
$this->render('update', array(
'model' => $model,
));
}
Is there a better way to do this when working with a MANY_MANY relation so I don’t run into any issues? Also notice how I have another HAS_MANY relation defined called $companyEmployees to access the middle table. I initially was just working with the MANY_MANY relation but couldn’t find an easy way to delete a row from the company_employee there without doing an extra CompanyEmployee::model()->find() statement.