TransWikia.com

Почему не работает $model->save() yii2

Stack Overflow на русском Asked on November 24, 2021

Контроллер

$companyObj = new Company();
           
$city = City::findOne(['name' => $post["CabinetRegistrationForm"]["city_name"]]);
            
$companyObj->name = $post["CabinetRegistrationForm"]["company_name"];
$companyObj->activity = 1;
$companyObj->district_id = $city->district_id;
$companyObj->region_id = $city->region_id;
$companyObj->municipality_id = $city->municipality_id;
$companyObj->city_id = $city->id;
$companyObj->address = $post["CabinetRegistrationForm"]["address"];
$companyObj->inn = $post["CabinetRegistrationForm"]["inn"];
$companyObj->approved = 0;
$companyObj->head_fio = $post["CabinetRegistrationForm"]["head_fio"];
$companyObj->phone = $post["CabinetRegistrationForm"]["phone"];
           
$companyObj->save();

Модель

namespace commonmodels;

use mdmadminmodelsAuthItem;
use Yii;
use yiibaseNotSupportedException;
use yiibehaviorsTimestampBehavior;
use yiidbActiveQuery;
use yiidbActiveRecord;
use yiidbQuery;
use yiihelpersArrayHelper;
use yiiwebIdentityInterface;

/**
 * This is the model class for table "company".
 *
 * @property int $id
 * @property string $name
 * @property string $org_form
 * @property string $activity
 * @property int $district_id
 * @property int $region_id
 * @property int $municipality_id
 * @property int $city_id
 * @property string $address
 * @property string $inn
 * @property int $approved
 * @property string $head_fio
 * @property string $phone
 * @property string $email
 * @property string $site
 *
 * @property DistrictModel $district
 * @property Municipality $municipality
 * @property City $city
 * @property User[] $users
 * @property SchoolClass[] $classes
 */
class Company extends commoncomponentsActiveRecord
{
    /**
     * {@inheritdoc}
     */
    public static function tableName()
    {
        return 'company';
    }

    /**
     * {@inheritdoc}
     */
    public function rules()
    {
        return [
            [['name', 'org_form', 'activity'], 'required'],
            [['district_id', 'region_id', 'municipality_id', 'city_id', 'approved'], 'integer'],
            [['address'], 'string'],
            [['name', 'org_form', 'activity', 'inn', 'head_fio', 'email', 'site', 'presentation_url'], 'string', 'max' => 255],
            [['phone'], 'string', 'max' => 50],
            [['district_id'], 'exist', 'skipOnError' => true, 'targetClass' => DistrictModel::className(), 'targetAttribute' => ['district_id' => 'id']],
            [['municipality_id'], 'exist', 'skipOnError' => true, 'targetClass' => Municipality::className(), 'targetAttribute' => ['municipality_id' => 'id']],
            [['presentation_url'], 'trim'],
        ];
    }

    /**
     * {@inheritdoc}
     */
    public function attributeLabels()
    {
        return [
            'id' => Yii::t('app', 'ID'),
            'name' => Yii::t('app', 'Name'),
            'org_form' => Yii::t('app', 'Org Form'),
            'activity' => Yii::t('app', 'Activity'),
            'district_id' => Yii::t('app', 'District ID'),
            'region_id' => Yii::t('app', 'Region ID'),
            'municipality_id' => Yii::t('app', 'Municipality ID'),
            'city_id' => Yii::t('app', 'City ID'),
            'address' => Yii::t('app', 'Address'),
            'inn' => Yii::t('app', 'Inn'),
            'approved' => Yii::t('app', 'Approved'),
            'head_fio' => Yii::t('app', 'Head Fio'),
            'phone' => Yii::t('app', 'Phone'),
            'email' => Yii::t('app', 'Email'),
            'site' => Yii::t('app', 'Site'),
            'presentation_url' => Yii::t('app', 'Presentation Url'),
        ];
    }

Вьюха

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

<div class="hidden">
<?= $form->field($model, 'role')->textInput() ?>
</div>
                
<?= $form->field($model, 'second_name')->textInput() ?>
<?= $form->field($model, 'name')->textInput() ?>
<?= $form->field($model, 'last_name')->input('last_name') ?>      
<?= $form->field($model, 'email')->input('email') ?>
<?= $form->field($model, 'inn')->widget(SuggestionsWidget::class, [
      'token' => '*******************',
                    
]) ?>
               
                
<?php if ($model->role == RoleModel::ROLE_RESEARCH_COORDINATOR_OO): ?>                  
<?= $form->field($model, 'company_name')->textarea(); ?>
<?= $form->field($model, 'city_name')->hiddenInput()->label(false); ?>
<?= $form->field($model, 'address')->hiddenInput()->label(false); ?>
<?= $form->field($model, 'head_fio')->hiddenInput()->label(false); ?>
<?= $form->field($model, 'phone')->hiddenInput()->label(false); ?>
<?php endif; ?>
..........

Вроде бы все правильно, никаких ошибок не выводится , $companyObj->errors – пустой массив, но $companyObj->save выдаёт false. В БД не появляется новая строка.
Помогите пожалуйста.

One Answer

Смотри, когда ты вызываешь метод save(), сначала идет валидация модели по правилам которые ты в rules() описал, если все ок, модель полетела на сохранение в бд. Значит что ошибки валидации все-таки есть. Вызови метод $companyObj->validate() затем посмотри что тут $companyObj->getErrors(), ошибки будут, гарантирую)))

Валидацию кстати отключить можно при сохранении, $companyObj->save(false)

Переписал бы контроллер:

        $model = new Company();

        if ($model->load(Yii::$app->request->post()) && $model->save()) {
            return $this->redirect(['view', 'id' => $model->id]);
        }

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

И часть из контроллера в модель бы выкинул:

    /**
     * @inheritDoc
     */
    public function beforeValidate(): bool
    {
        $post = Yii::$app->request->post();

        $city = City::findOne(['name' => $post["CabinetRegistrationForm"]["city_name"]]);

        $this->activity = 1;
        $this->district_id = $city->district_id;
        $this->region_id = $city->region_id;
        $this->municipality_id = $city->municipality_id;
        $this->city_id = $city->id;
        $this->approved = 0;

        return parent::beforeValidate();
    }

Хотя этот твой поиск города исходя из данных формы, хз стремно как-то... По инкапсуляции тоже жестко) Бери да подставляй данные какие хочешь)

Запомни, в rules() описываешь только те поля которые есть в форме. Форма на 3 поля, в rules() 3 поля и описываешь, иначе все остальные аттрибуты подменить на любые можно будет))))

А как из POST писать данные в модель правильно?

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

  • Загружаешь данные в модель из post
  • Значения присвоятся только тем аттрибутам, которые описаны в rules(), все остальное будет проигнорировано.
  • По поводу пачки hiddenInput() хз, как по мне они где-то на фоне у модели должны присваиваться, но раз уже так сделал, то нужно на них дополнительные валидаторы написать, чтобы ты был точно уверен, что никакой подмены не будет.

Answered by Михаил Динов on November 24, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP