Suppose you want to have a list in Category with its related products and you want to updates the list (removing or insert product items) This wiki show us how to do that
schema: Model Product (id,name,price,category_id) Model Category (id,name)
So in this case a product has only one category and category has many products
In the Category.php model
public function relations() {
return array(
...
'relatedProducts' => array(self::HAS_MANY, 'Product', 'category_id'),
);
}
public function rules() {
return array(
...
array('product_ids', 'type', 'type' => 'array', 'allowEmpty' => true),
);
}
public $product_stored_ids = array();
public $product_ids = array();
public function afterFind() {
$this->product_ids = [];
foreach ($this->relatedProducts as $r) {
$this->product_ids[] = $r->id;
}
$this->product_stored_ids = $this->product_ids;
parent::afterFind();
}
protected function afterSave() {
if (!$this->product_ids) //if nothing selected set it as an empty array
$this->product_ids = array();
//save the new selected ids that are not exist in the stored ids
$ids_to_update = array_diff($this->product_ids, $this->product_stored_ids);
foreach ($ids_to_update as $uid) {
$p = Product::model()->findByPk($uid);
if ($p) {
$p->category_id = $this->id;
$p->save();
}
}
//remove the stored ids that are not exist in the selected ids
$ids_to_remove = array_diff($this->product_stored_ids, $this->product_ids);
foreach ($ids_to_remove as $did) {
if ($p = Product::model()->findByPk()) {
$p->category_id = NULL;
$p->save();
}
}
parent::afterSave();
}
view/category/_form.php
<?php
$form = $this->beginWidget('CActiveForm', array(
'id' => 'category-form',
'enableAjaxValidation' => false,
));
?>
<h2>Products in category</h2>
<?php
$data = CHtml::listData(Product::model()->findAll(), 'id', 'Title');
echo $form->listBox($model, 'product_ids', $data, array('multiple' => 'true'));
//or echo $form->checkBoxList($model, 'product_ids', $data);
?>
<div class="row buttons">
<?php echo CHtml::submitButton($model->isNewRecord ? 'Create' : 'Save'); ?>
</div>
<?php $this->endWidget(); ?>
If you have any questions, please ask in the forum instead.
Signup or Login in order to comment.