You are viewing revision #1 of this wiki article.
This is the latest version of this article.
In this wiki I will show you how to save/update a model with many related model For example: How to set a product to multiple categories only in one post form ?
Schema database table
Product:id,title,... Category:id,title,... product_to_category: id,productId,categoryId,...
You have to add the below code in your Model and View (Suppose you have already creates the default MVC for Product)
So,
Model:
//1)add validator to allow multiple values
public function rules() {
return array(
...
array('toCat', 'type', 'type' => 'array', 'allowEmpty' => false),
...
);
}
//2)stored and inserted values
public $toCat = [];
public $toCat_stored = [];
//retrieve the related ids
public function afterFind() {
$this->toCat_stored = [];
foreach ($this->productsToCategories as $r) { //productsToCategories is relation with table product_to_category
$this->toCat[] = $r->CategoryId;
}
$this->toCat_stored = $this->ItemToCat;
parent::afterFind();
}
//3) save the selected categories, remove the unselected categories
protected function afterSave() {
if (!$this->toCat) //if nothing selected set it as an empty array
$this->ItemToCat = array();
//save the new selected ids that are not exist in the stored ids
$ids_to_insert = array_diff($this->toCat, $this->toCat_stored);
foreach ($ids_to_insert as $nid) {
$m = new ProductToCategory();
$m->productId = $this->id;
$m->CategoryId = $nid;
$m->save();
}
//remove the stored ids that are not exist in the selected ids
$ids_to_delete = array_diff($this->ItemToCat_stored, $this->ItemToCat);
foreach ($ids_to_delete as $did) {
if ($d = ProductToCategory::model()->findByAttributes(['productId' => $this->id, 'CategoryId' => $did])) {
$d->delete();
}
}
parent::afterSave();
}
Controller: nothing special, save model and render view as usually
View: (_form.php)
In your form widget add the below code before submit button
<div>
<?php
$allcats = CHtml::listData(Category::model()->findAll(),'id','title');
echo '<table style="width:50%;"><thead><tr><th>category</th><th>checked</th></tr><thead><tbody>';
foreach ($allcats as $catId => $catTitle) :
$isChecked = in_array($catId, $model->toCat);
echo '<tr>';
echo '<td>' . $catTitle . '</td>';
echo '<td>' . CHtml::checkBox('Product[toCat][]', $isChecked, array('value' => $catId)) . '</td>';
echo '</tr>';
endforeach;
echo '</tbody></table>';
?>
</div>
Enjoy it!
Duplicate
This is already discussed in a few earlier wikis. You may want to remove and merge.
For Yii 1.x here, and other wikis as well.
For Yii 2.x here
Please merge
+1 for richard's comment, here is another wiki that discusses same, please merge so we do not have duplicate wikis.
Re: Duplicate 17326
All these related wikis has the same approach but has also differences,
so it is good for the community to has an integrated point of view
In addition many wiki's works fine both of Yii version 1.x , 2.x but exists in two versions...
Re: Please merge #17327
langy, the answer is the same (#17327)
If you have any questions, please ask in the forum instead.
Signup or Login in order to comment.