How to set multi select value from array object in yii2 while updating

可紊 提交于 2019-12-22 14:58:27

问题


I have table which have multiple reference to ohter tables like

user
id         name         email
categories
id         title
user_categories
user_id    category_id

Here a user will have multiple category associated with him/her

I am able to save these successfully with new records like following

View File:

echo $form->field($package_categories, 'category_id')->dropDownList( ArrayHelper::map(
StudyMaterialCategories::find()->all(), 'id', 'title'), 
['multiple' => true]
);

Save New record:

$model = new Packages();
$package_categories = new PackageCategories();
$request = Yii::$app->request;
if ($request->isPost) {
    $transaction = Yii::$app->db->beginTransaction();
    try {
        $post = $request->post();
        $model->load($post);
        $model->save();
        foreach ($post['PackageCategories']['category_id'] as $key => $value) {
            $package_categories = new PackageCategories();
            $package_categories->category_id = $value;
            $package_categories->package_id = $model->id;
            $package_categories->save();
        }
        $transaction->commit();
        return $this->redirect(['view', 'id' => $model->id]);
    } catch (Exception $ex) {
        $transaction->rolback();
        Yii::$app->session->setFlash("error", $ex->getMessage());
    }
}

Till now It's running successfully.

But I'm stuck when going to update the table. The problem part is dropdown list. How to set multiple selected option as per database if I'm coming with array of object. Have a look on the following code

$package_categories = PackageCategories::find()
->where('package_id=:package_id', ['package_id' => $id])->all();
if (count($package_categories) < 1) {
    $package_categories = new PackageCategories();
}
$request = Yii::$app->request;
if ($request->isPost) {
    $transaction = Yii::$app->db->beginTransaction();
    try {
        $post = $request->post();
        $model->load($post);
        $model->save();
        $package_categories = new PackageCategories();
        $package_categories->deleteAll(
            "package_id=:package_id", 
            [':package_id' => $model->id]
        );
        foreach ($post['PackageCategories']['category_id'] as $key => $value) {
            $package_categories = new PackageCategories();
            $package_categories->category_id = $value;
            $package_categories->package_id = $model->id;
            $package_categories->save();
        }
        $transaction->commit();
        return $this->redirect(['view', 'id' => $model->id]);
    } catch (Exception $ex) {
        $transaction->rolback();
        Yii::$app->session->setFlash("error", $ex->getMessage());
    }
}

if I try to get first object of the array $package_categories of only able to set selected one option


回答1:


This is an example code of a model class Permit which has a many to many relationship with Activity through PermitActivity (pivot table model).

Model Class Activity

public class Permit extends \yii\db\ActiveRecord {
    public $activities_ids;
    ...
    public function rules() {
        return [
            ...
            [['activities_ids'], 'safe'],
            ...
        ];
    }
    ...
    // Method called after record is saved, be it insert or update.
    public function afterSave($insert, $changedAttributes) {
        // If this is not a new record, unlink all records related through relationship 'activities'
        if(!$this->isNewRecord) {
            // We unlink all related records from the 'activities' relationship.
            $this->unlinkAll('activities', true);
            // NOTE: because this is a many to many relationship, we send 'true' as second parameter
            // so the records in the pivot table are deleted. However on a one to many relationship
            // if we send true, this method will delete the records on the related table. Because of this,
            // send false on one to many relationships if you don't want the related records deleted.
        }

        foreach($this->activities_ids as $activity_id) {
            // Find and link every model from the array of ids we got from the user.
            $activity = Activity::findOne($activity_id);
            $this->link('activities', $activity);
        }

        parent::afterSave($insert, $changedAttributes);
    }
    ...
    // Declare relationship with Activity through the pivot table permitActivity
    public function getActivities(){
        return $this->hasMany(Activitiy::className(), ['id' => 'activity_id'])
            ->viaTable('permitActivity',['permit_id' => 'id']);
    }
    ...
    public function afterFind(){
        parent::afterFind();
        $this->activities_id = ArrayHelper::getColumn($this->activities, 'id');
    }
}

This way the model class is the one responsible for creating and updating the relationship using the pivot table.

The most important thing is to have the relationship method declared correctly.

Edit

This is an example of the view using kartikv\widgets\Select2. I don't really know if dropDownList supports multiple select, however Select2 has so many useful features i usually use it over other options.

echo $form->field($model, 'activities')->widget(Select2::classname(), [
    'data' => $data,
    'options' => [
        'placeholder' => '...'
    ],
    'pluginOptions' => [
        'allowClear' => true,
        'multiple' => true,
    ],
]);


来源:https://stackoverflow.com/questions/41904487/how-to-set-multi-select-value-from-array-object-in-yii2-while-updating

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!