Добавление данных сразу в несколько таблиц

Общие вопросы по использованию второй версии фреймворка. Если не знаете как что-то сделать и это про Yii 2, вам сюда.
Anton1999
Сообщения: 26
Зарегистрирован: 2017.04.28, 14:55

Добавление данных сразу в несколько таблиц

Сообщение Anton1999 »

ОТРЕДАКТИРОВАНО. Весь код из комментариев вынесен сюда.
Всем привет. Вот только стал изучать данный фреймворк, он же первый фреймворк который я изучаю. И у меня возник вопрос.
У меня есть 2 таблицы. В первой таблице TABLE_SITY у меня содержаться данные о городах. Во второй таблице TABLE_STREETS у меня содержаться данные об улицах. При добавлении нового города или при редактировании существующего города мне нужно сделать добавление/удаление улиц к нему и сохранение этого в бд. Реализовывал это с помощью виджета https://wbraganca.com/yii2extensions/dy ... ource-code. При добавлении нового города снизу на странице появилась кнопка "Добавить улицу". Все отображается на странице корректно, но вот при нажатии на клавишу "Добавить улицу" ничего не происходит. В чем проблема тут?

Вот код модели TABLE_SITY:

Код: Выделить всё

<?php

namespace backend\models;

use Yii;

/**
 * This is the model class for table "TABLE_SITY".
 *
 * @property integer $ID			// Автоматическое заполнение
 * @property string $NAME_SITY		// Заполняемое поле
 * @property string $DESC_SITY		// Заполняемое поле
 * @property string $LIST_ATTRAC	// Заполняемое поле
 * @property integer $RAND		// Заполняемое поле
 *
 */
class TableSity extends \yii\db\ActiveRecord
{
    public static function tableName()
    {
        return 'TABLE_SITY';
    }

    public function rules()
    {
        return [
            [['NAME_SITY'], 'required'],
            [['RAND'], 'integer'],
            [['NAME_SITY'], 'string', 'max' => 100],
            [['DESC_SITY', 'LIST_ATTRAC'], 'string', 'max' => 1000],
            [['ID'], 'unique'],
        ];
    }

    public function attributeLabels()
    {
        return [
            'ID' => 'ID Города',
            'NAME_SITY' => 'Название города',
            'DESC_SITY' => 'Описание города',
            'LIST_ATTRAC' => 'Список достопримечательностей',
            'RAND' => 'Включен в список случайных городов',
        ];
    }
    
    public function getIDSTREETs()
    {
        return $this->hasMany(TableStreets::className(), ['ID_SITY' => 'ID']);
    }
}
Вот код модели TABLE_STREETS

Код: Выделить всё

<?php

namespace backend\models;

use Yii;

/**
 * This is the model class for table "TABLE_STREETS".
 *
 * @property integer $ID_STREET   		// Автоматическое заполнение
 * @property integer $ID_SITY			// Автоматическое заполнение
 * @property string $NAME_STREET        	// Заполняемое поле
 * @property string $DESC_STREET        	// Заполняемое поле
 * @property integer $RAND_STREET       	// Заполняемое поле
 *
 */
class TableStreets extends \yii\db\ActiveRecord
{
    public static function tableName()
    {
        return 'TABLE_STREETS';
    }

    public function rules()
    {
        return [
            [['ID_SITY', 'NAME_STREET'], 'required'],
            [['ID_SITY', 'RAND_STREET', 'STATUS'], 'integer'],
            [['NAME_STREET'], 'string', 'max' => 100],
            [['DESC_STREET'], 'string', 'max' => 1000],
            [['ID_STREET'], 'unique'],
            [['ID_SITY'], 'exist', 'skipOnError' => true, 'targetClass' => TABLESITY::className(), 'targetAttribute' => ['ID_SITY' => 'ID']],
        ];
    }

    public function attributeLabels()
    {
        return [
            'ID_STREET' => 'ID Улицы',
            'ID_SITY' => 'ID Города',
            'NAME_STREET' => 'Название улицы',
            'DESC_STREET' => 'Описание улицы',
            'RAND_STREET' => 'Включен в список случайных улиц',
        ];
    }

    public function getIDSITY()
    {
        return $this->hasOne(TABLESITY::className(), ['ID' => 'ID_SITY']);
    }
}
Код контроллера:

Код: Выделить всё

public function actionCreate()
    {
        $model = new TableSity();
        $modelsTs = [new TableStreets];

        if ($model->load(Yii::$app->request->post())) {

            $modelsTs = Model::createMultiple(TableStreets::className());
            Model::loadMultiple($modelsTs, Yii::$app->request->post());

            // Validate all models
            $valid = $model->validate();
            $valid = Model::validateMultiple($modelsTs) && $valid;

            if ($valid) {
                $transaction = \Yii::$app->db->beginTransaction();
                try {
                    if ($flag = $model->save(false)) {
                        foreach ($modelsTs as $modelTs) {
                            $modelTs->ID_SITY = $model->ID;
                            if (! ($flag = $modelTs->save(false))) {
                                $transaction->rollBack();
                                break;
                            }
                        }
                    }
                    if ($flag) {
                        $transaction->commit();
                        return $this->redirect(['view', 'id' => $model->ID]);
                    }
                } catch (Exception $e) {
                    $transaction->rollBack();
                }
            }
        } else {
            return $this->render('create', [
                'model' => $model,
                'modelsTs' => (empty($modelTs)) ? [new TableStreets] : $modelTs,
            ]);
        }
    }

public function actionUpdate($id)
{
	$model = $this->findModel($id);
	$modelsTs = $model->iDSTREETs;

	if ($model->load(Yii::$app->request->post()) && $model->save()) {

		$oldIDsStreet = ArrayHelper::map($modelsTs, 'ID', 'ID');
		$modelsTs = Model::createMultiple(TableStreets::classname(), $modelsTs);
		Model::loadMultiple($modelsTs, Yii::$app->request->post());
		$deletedIDsStreet = array_diff($oldIDsAnswers, array_filter(ArrayHelper::map($modelsTs, 'ID', 'ID')));

		// Validate all models
            $valid = $model->validate();
            $valid = Model::validateMultiple($modelsTs) && $valid;

            if ($valid) {
                $transaction = \Yii::$app->db->beginTransaction();
                try {
                    if ($flag = $model->save(false)) {
						if (!empty($deletedIDsAnswers)) {
							TableStreets::deleteAll(['ID' => $deletedIDsStreet]);
						}
                        foreach ($modelsTs as $modelTs) {
                            $modelTs->ID_SITY = $model->ID;
                            if (! ($flag = $modelTs->save(false))) {
                                $transaction->rollBack();
                                break;
                            }
                        }
                    }
                    if ($flag) {
                        $transaction->commit();
                        return $this->redirect(['view', 'id' => $model->ID]);
                    }
                } catch (Exception $e) {
                    $transaction->rollBack();
                }
            }
        } else {
            return $this->render('create', [
                'model' => $model,
                'modelsTs' => (empty($modelTs)) ? [new TableStreets] : $modelTs,
            ]);
        }
	}
}
Код create.php, update.php:

Код: Выделить всё

<?php

use yii\helpers\Html;

/* @var $this yii\web\View */
/* @var $model backend\models\TableSity */

$this->title = 'Добавление нового Города';
$this->params['breadcrumbs'][] = ['label' => 'Список городов', 'url' => ['index']];
$this->params['breadcrumbs'][] = $this->title;

?>

<div class="tablesity-create">

    <h1><?= Html::encode($this->title) ?></h1>

    <?= $this->render('_form', [
        'model' => $model,
        'modelsTs' => $modelsTs,
    ]) ?>

</div>

Код формы:

Код: Выделить всё

<?php

use yii\helpers\Html;
use yii\widgets\ActiveForm;

use dosamigos\ckeditor\CKEditor;
use wbraganca\dynamicform\DynamicFormWidget;

?>

<div class="tablesity-form">

    <?php $form = ActiveForm::begin(['id' => 'dynamic-form']); ?>

    <?= $form->field($model, 'NAME_SITY')->textInput(['maxlength' => true]) ?>

    <?= $form->field($model, 'DESC_SITY')->widget(CKEditor::className(), [
        'options' => ['rows' => 6],
        'preset' => 'basic'
    ]) ?>

    <?= $form->field($model, 'LIST_ATTRAC')->widget(CKEditor::className(), [
        'options' => ['rows' => 6],
        'preset' => 'basic'
    ]) ?>

    <?= $form->field($model, 'RAND')->checkbox() ?>

    <!-- Добавление начато -->
	<div class="panel panel-default">
	<div class="panel-heading">
            <h4> Добавление улиц</h4>
        </div>
        <div class="panel-body">
    <?php DynamicFormWidget::begin([
        'widgetContainer' => 'dynamicform_wrapper',
        'widgetBody' => '.container-items',
        'widgetItem' => '.item',
        'limit' => 4,
        'min' => 0,
        'insertButton' => '.add-item',
        'deleteButton' => '.remove-item',
        'model' => $modelsTs[0],
        'formId' => 'dynamic-form',
        'formFields' => [
            'NAME_STREET',
            'DESC_STREET',
            'RAND_STREET',
			'STATUS',
        ],
    ]); ?>

        <div class="panel-body container-items"><!-- widgetContainer -->
            <?php foreach ($modelsTs as $index => $modelTs): ?>

                <div class="item panel panel-default"><!-- widgetBody -->

                    <div class="panel-heading">
                        <span class="panel-title-street">Улицы: <?= ($index + 1) ?></span>
                        <button type="button" class="pull-right remove-item btn btn-danger btn-xs"><i class="fa fa-minus"></i></button>
                        <div class="clearfix"></div>
                    </div>

                    <div class="panel-body">
                        <?php
                        // necessary for update action.
                        if (!$modelTs->isNewRecord) {
                            echo Html::activeHiddenInput($modelTs, "[{$index}]ID_STREET");
                        }
                        ?>

                        <?= $form->field($modelTs, "[{$index}]NAME_STREET")->textInput(['maxlength' => true]) ?>
						
                        <?= $form->field($modelTs, "[{$index}]DESC_STREET")->textInput(['maxlength' => true]) ?>

                        <?= $form->field($modelTs, "[{$index}]RAND_STREET")->checkbox() ?>
						
						<?= $form->field($modelTs, "[{$i}]STATUS")->checkbox() ?>
                        
                    </div>

                </div>

            <?php endforeach; ?>
        </div>

    </div>

    <?php DynamicFormWidget::end(); ?>
    <!-- Добавление окончено -->

    <div class="form-group">
        <?= Html::submitButton($model->isNewRecord ? 'Добавить город' : 'Применить изменения', ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?>
    </div>

    <?php ActiveForm::end(); ?>

</div>
Вот как отображается
Изображение
Последний раз редактировалось Anton1999 2017.05.23, 10:53, всего редактировалось 7 раз.
Аватара пользователя
rodion_zlobin
Сообщения: 207
Зарегистрирован: 2017.01.11, 16:33

Re: Добавление данных сразу в несколько таблиц

Сообщение rodion_zlobin »

https://github.com/wbraganca/yii2-dynamicform отлично подойдет для этих задач
Anton1999
Сообщения: 26
Зарегистрирован: 2017.04.28, 14:55

Re: Добавление данных сразу в несколько таблиц

Сообщение Anton1999 »

rodion_zlobin писал(а): 2017.05.16, 11:10 https://github.com/wbraganca/yii2-dynamicform отлично подойдет для этих задач
Я посмотрел 3 дэмки и понял что мне подойдет 1-я дэмка.
https://wbraganca.com/yii2extensions/dy ... ource-code
Вот тут стал смотреть исходный код и не могу понять следующее

Source Code - Controller

Код: Выделить всё

public function actionView($id)
    {
        $model = $this->findModel($id);
        $addresses = $model->addresses;

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

интересует строка: $addresses = $model->addresses;
модель обращается к какому то addresses? откуда она взялась? что мне вместо этого addresses туда писать? я что то в коде ничего не нашел. и в бд там ничего подобного нету.
Аватара пользователя
ElisDN
Сообщения: 5845
Зарегистрирован: 2012.10.07, 10:24
Контактная информация:

Re: Добавление данных сразу в несколько таблиц

Сообщение ElisDN »

Anton1999 писал(а): 2017.05.16, 14:19 откуда она взялась? что мне вместо этого addresses туда писать? я что то в коде ничего не нашел. и в бд там ничего подобного нету.
https://github.com/yiisoft/yii2/blob/ma ... и-данными-
Anton1999
Сообщения: 26
Зарегистрирован: 2017.04.28, 14:55

Re: Добавление данных сразу в несколько таблиц

Сообщение Anton1999 »

Помогите пожалуйста, делаю по примеру create.php (https://wbraganca.com/yii2extensions/dy ... ource-code).
И на выходе получаю ошибку: Attribute name must contain word characters only. Что не так?
Последний раз редактировалось Anton1999 2017.05.17, 14:04, всего редактировалось 4 раза.
Аватара пользователя
rodion_zlobin
Сообщения: 207
Зарегистрирован: 2017.01.11, 16:33

Re: Добавление данных сразу в несколько таблиц

Сообщение rodion_zlobin »

А в каком месте ошибка возникает?
Anton1999
Сообщения: 26
Зарегистрирован: 2017.04.28, 14:55

Re: Добавление данных сразу в несколько таблиц

Сообщение Anton1999 »

rodion_zlobin писал(а): 2017.05.17, 09:11 А в каком месте ошибка возникает?
Когда открываю страницу с созданием нового города
Аватара пользователя
rodion_zlobin
Сообщения: 207
Зарегистрирован: 2017.01.11, 16:33

Re: Добавление данных сразу в несколько таблиц

Сообщение rodion_zlobin »

Не в дебагере в каком месте кода?
Anton1999
Сообщения: 26
Зарегистрирован: 2017.04.28, 14:55

Re: Добавление данных сразу в несколько таблиц

Сообщение Anton1999 »

rodion_zlobin писал(а): 2017.05.17, 09:37 Не в дебагере в каком месте кода?
Вообще ошибка выглядит вот так:
Изображение

Поставил phpStorm сейчас и стал проверять код.
И вот только заметил, что в create.php

Код: Выделить всё

<div class="tablesity-create">

    <h1><?= Html::encode($this->title) ?></h1>

    <?= $this->render('_form', [
        'model' => $model,
        'modelTs' => $modelTs,
    ]) ?>

</div>
нету такой переменной "=> $modelTs,", хотя я ее передаю с контроллера.
Аватара пользователя
rodion_zlobin
Сообщения: 207
Зарегистрирован: 2017.01.11, 16:33

Re: Добавление данных сразу в несколько таблиц

Сообщение rodion_zlobin »

Нет, переменная передается. скрин ниже опустите, и мы тогда увидим в какой части кода ошибка вылезла... :)
Anton1999
Сообщения: 26
Зарегистрирован: 2017.04.28, 14:55

Re: Добавление данных сразу в несколько таблиц

Сообщение Anton1999 »

rodion_zlobin писал(а): 2017.05.17, 09:54 Нет, переменная передается. скрин ниже опустите, и мы тогда увидим в какой части кода ошибка вылезла... :)
Я удалил и строчку заново стал писать. И когда дохожу до 'modelTs' => $ , то мне в подсказке выскакивает только $model, а $modelTs там нет. и когда сам ее напишу, то она серым горит.

Вот что ниже написано:
Изображение
Аватара пользователя
rodion_zlobin
Сообщения: 207
Зарегистрирован: 2017.01.11, 16:33

Re: Добавление данных сразу в несколько таблиц

Сообщение rodion_zlobin »

У вас в моделе есть поле STATUS, а инпута под него нету, это что в глаза бросилось
Anton1999
Сообщения: 26
Зарегистрирован: 2017.04.28, 14:55

Re: Добавление данных сразу в несколько таблиц

Сообщение Anton1999 »

rodion_zlobin писал(а): 2017.05.17, 10:29 У вас в моделе есть поле STATUS, а инпута под него нету, это что в глаза бросилось
ну вообще это автозаполняемое поле в бд. я сейчас его удалил отсюда

Код: Выделить всё

<?php DynamicFormWidget::begin([
        'widgetContainer' => 'dynamicform_wrapper',
        'widgetBody' => '.container-items',
        'widgetItem' => '.item',
        'limit' => 4,
        'min' => 0,
        'insertButton' => '.add-item',
        'deleteButton' => '.remove-item',
        'model' => $modelTs[0],
        'formId' => 'dynamic-form',
        'formFields' => [
		'NAME_STREET',
            	'DESC_STREET',
            	'RAND_STREET',
        ],
    ]); ?>
И получил теперь 2 такие вот ошибки:
Изображение
Anton1999
Сообщения: 26
Зарегистрирован: 2017.04.28, 14:55

Re: Добавление данных сразу в несколько таблиц

Сообщение Anton1999 »

rodion_zlobin писал(а): 2017.05.17, 10:29 У вас в моделе есть поле STATUS, а инпута под него нету, это что в глаза бросилось
Вот нашел решение вроде как, надо поставить @dev версию через composer. Стоит ли ставить дев версию? По логике она ведь может быть не стабильна
Anton1999
Сообщения: 26
Зарегистрирован: 2017.04.28, 14:55

Re: Добавление данных сразу в несколько таблиц

Сообщение Anton1999 »

Действительно, после установки @dev версии сразу все заработало. Только вот столкнулся с проблемой, при нажатии на клавишу "добавить улицу" ничего не происходит, в чем может быть проблема? код представлен выше.

Вот как стало отображаться
Изображение
Аватара пользователя
rodion_zlobin
Сообщения: 207
Зарегистрирован: 2017.01.11, 16:33

Re: Добавление данных сразу в несколько таблиц

Сообщение rodion_zlobin »

консоль что пишет?
Anton1999
Сообщения: 26
Зарегистрирован: 2017.04.28, 14:55

Re: Добавление данных сразу в несколько таблиц

Сообщение Anton1999 »

rodion_zlobin писал(а): 2017.05.17, 12:12 консоль что пишет?
какая консоль? в браузере?

Изображение
Anton1999
Сообщения: 26
Зарегистрирован: 2017.04.28, 14:55

Re: Добавление данных сразу в несколько таблиц

Сообщение Anton1999 »

rodion_zlobin писал(а): 2017.05.17, 12:12 консоль что пишет?
Я вынес весь код в описание темы. Вы сможете помочь с этим? При нажатии на клавишу "Добавить улицу" ничего не происходит. Я никак не могу разобраться в чем проблема
Аватара пользователя
rodion_zlobin
Сообщения: 207
Зарегистрирован: 2017.01.11, 16:33

Re: Добавление данных сразу в несколько таблиц

Сообщение rodion_zlobin »

<?php $form = ActiveForm::begin(['id' => 'dynamic-form']); ?>
Anton1999
Сообщения: 26
Зарегистрирован: 2017.04.28, 14:55

Re: Добавление данных сразу в несколько таблиц

Сообщение Anton1999 »

rodion_zlobin писал(а): 2017.05.17, 18:15 <?php $form = ActiveForm::begin(['id' => 'dynamic-form']); ?>
Все равно ничего не происходит при нажатии на кнопку "добавить улицу".

Я так понимаю что не срабатывает кнопка, но почему так происходит не могу понять.

Код: Выделить всё

<div class="panel-heading">
     <i class="fa fa-envelope"></i> Ответы
     <button type="button" class="pull-right add-item btn btn-success btn-xs"><i class="fa fa-plus"></i> Добавить ответ</button>
     <div class="clearfix"></div>
</div>
Закрыто