Yii2 сохранение многие-ко-многим в одной модели

1. Подготовим вывод параметров
\views\pers\_form.php

    <?php
    if ($model->isNewRecord)
    {
        $result = $model->inputAtr();
    }
    else
    {
        $result = $model->updAtr($model->id);
    };
    ?>
    <?php
    for($i = 0; $i < count($result); $i++)
    {
        (!empty ($result[$i]['value'])) ? $value = $result[$i]['value'] : $value = 10;
        ?>
        <p> <?= $result[$i]['name']; ?></p>
        <input type="number" min="1" max="100" step="1" value="<?= $value; ?>" name="Param[<?= $result[$i]['id']; ?>]" class='form-control'>
        <?php
    }
    ?>

2.Функции в модели
\models\Pers.php
public function inputAtr()
    {
        $connection = Yii::$app->getDb();
        $command = $connection->createCommand("
                                                SELECT id,
                                                       name
                                                FROM param p
                                                WHERE p.id != p.param_id
                                                  AND p.param_id = 1
                                              ");
        $result = $command->queryAll();
        return $result;
    }
    
    public function updAtr($pers)
    {
        $connection = Yii::$app->getDb();
        $command = $connection->createCommand("
                                                SELECT p.id,
                                                       p.name,
                                                       p.info,
                                                       p.param_id,
                                                       pp.value
                                                FROM param p
                                                LEFT JOIN pers_param pp ON (pp.param_id = p.id
                                                                            AND pp.pers_id = $pers)
                                                WHERE p.param_id = 1
                                                  AND p.id != p.param_id
                                              ");
        
        $result = $command->queryAll();        
        return $result;
    }

3. Контролер
\controllers\PersController.php

    public function actionCreate()
    {
        $model = new Pers();
        $model->loadDefaultValues();

        if ($model->load(Yii::$app->request->post()) && $model->save())
        {
            $last_id = $model->id;
            $param = Yii::$app->request->post('Param');

            $connection = \Yii::$app->db;
            foreach($param as $id => $value)
            {
                $connection->createCommand()
                        ->insert('pers_param', [
                            'pers_id' => $last_id,
                            'param_id' => $id,
                            'value' => $value
                        ])->execute();
            }
            return $this->redirect(['view', 'id' => $last_id]);
        }

        return $this->render('create', [
                    'model' => $model,
        ]);
    }

    /**
     * Updates an existing Pers model.
     * If update is successful, the browser will be redirected to the 'view' page.
     * @param integer $id
     * @return mixed
     */
    public function actionUpdate($id)
    {
        $model = $this->findModel($id);
        if ($model->load(Yii::$app->request->post()) && $model->save())
        {
            $param = Yii::$app->request->post('Param');
            $connection = \Yii::$app->db;
            foreach($param as $id_param => $value)
            {
                $command = $connection->createCommand(
                        "INSERT INTO pers_param (pers_id, param_id, value) VALUE ( $id, $id_param, $value) ON DUPLICATE KEY
                            UPDATE value = $value;");
                $command->execute();
            }
            return $this->redirect(['view', 'id' => $model->id]);
        }
        
        return $this->render('update', [
                    'model' => $model,
        ]);
    }

4. Удаление из сводной таблицы будет происходить за счет внешних ключей
DDL pers_param
CREATE TABLE `pers_param` (
  `id` INTEGER(11) NOT NULL AUTO_INCREMENT,
  `pers_id` INTEGER(11) NOT NULL COMMENT 'персонаж',
  `param_id` INTEGER(11) NOT NULL COMMENT 'параметр',
  `value` INTEGER(11) NOT NULL DEFAULT 1 COMMENT 'значение',
  `f_time` TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6) COMMENT 'создано',
  PRIMARY KEY (`id`) USING BTREE,
  UNIQUE KEY `pers_param_idx1` (`pers_id`, `param_id`) USING BTREE,
  KEY `fk_pers_has_param_param2_idx` (`param_id`) USING BTREE,
  KEY `fk_pers_has_param_pers2_idx` (`pers_id`) USING BTREE,
  CONSTRAINT `fk_pers_has_param_param2` FOREIGN KEY (`param_id`) REFERENCES `param` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
  CONSTRAINT `fk_pers_has_param_pers2` FOREIGN KEY (`pers_id`) REFERENCES `pers` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB
AUTO_INCREMENT=47 CHARACTER SET 'utf8' COLLATE 'utf8_unicode_ci'
COMMENT='базовые параметры персонажа'
;


5. Настроим GridView
    <?php
    $model = new Pers();
    $result = $model->inputAtr();  //получаем список атрибутов
    $column = [
        ['class' => 'yii\grid\SerialColumn'],
        'id',
        'name:ntext',
        'info:ntext',
        'img:ntext',
        'lvl',
    ];

    for($i = 0; $i < count($result); $i++)
    {
        $res = $result[$i]['id'];
        $myparam = [
            'attribute' => $result[$i]['name'],
            'format' => 'raw',
            'value' => function ($model) use ($res)
              {
                return $model->myval($model->id, $res); //добавляем свои данные
              }, 
        ];
        $column[] = $myparam;
    }

    $column[] = ['class' => 'yii\grid\ActionColumn'];
    ?>
    <?=
    GridView::widget([
        'dataProvider' => $dataProvider,
        'filterModel' => $searchModel,
        'columns' => $column,
    ]);
    ?>

и в модели
    public function myval($id_pers, $id_param)
    { 
            $model = Pparam::find('value')
        ->where(['pers_id' => $id_pers, 'param_id' => $id_param])
        ->scalar(); 
            return  $model;
    }

6. DetailView
    <?php
    $model_ = new Pers();
    $result = $model_->inputAtr();
    $column = [
            'id',
            'name:ntext',
            'info:ntext',
            'img:ntext',
            'lvl',
            'lvlup',
            'exp',
            'race_id'
        ];

    for($i = 0; $i < count($result); $i++)
    {
        $res = $result[$i]['id'];
        $myparam = [
            'label' => $result[$i]['name'],
            'value' => $model->myval($model->id, $res), 
        ];
        $column[] = $myparam;
    }

    ?>
    <?=
    DetailView::widget([
        'model' => $model,
        'attributes' => $column,
    ]);
    ?>




_

Популярные сообщения из этого блога

Пишем логи на C# (.NET). Легкий способ.

Авторизация yii 2 из базы

Средства для работы с базой данный PostgreSql