Search code examples
phpdatabaseformsoopyii2

Yii2 how do I update data from 2 database tables in one form


I have this form and I'm trying to update it using a class and a controller, but I can't make it work. the database looks like this:

person:                           Code:             Pets:
id| PersonId | name  | power      Id | PesonId      Id | Kind | PersonId | type
1 | 111      | Lufy  | Elastic    1  | 111          1  | Dog  | 190      | Dog
5 | 190      | Ace   | Fire       2  | 190          2  | Cat  | 190      | Cat

The form looks like this:

class Form extends Model
{
    /**
    * @var string
    */
    public $name;

    /**
    * @var string
    */
    public $power;

    /**
    * @var string
    */
    public $kind
 
    public function rules()
    {
        return [['name','power','kind']]
    }

    public function attributeLabels()
    {
        return [
            'name' => 'Name',
            'power' => 'Power',
            'kind' => 'Kind' 
        ];
    }
}

View:

use models\Form;

/**
* @var $form Form
*/

<?php $form = ActiveForm::begin(['type' => ActiveForm::TYPE_HORIZONTAL]); ?>
<?= $form->field($form, 'name'); ?>
<?= $form->field($form, 'power'); ?>
<?= $form->field($form, 'kind'); ?>

<?= Html::sterSubmitButton('Save'); ?>

<?php
ActiveForm::end();

Then I have the controller:

class FormController extends Controller
{
    /**
     * @return string
     */
    public function actionIndex()
    {
        $form = new Form();

        if (Yii::$app->request->isPost && $form->load(Yii::$app->request->post())) {
            $formClass = new FormClass($form);
            $webshop->processForm($webshopForm);
        }

        $formClass = new FormClass($form);
        return $this->render('index', [
            'form' => $formClass->getForm(),
        ]);
    }
}

Class:

class ClassForm
{
    /**
    * @var Person
    */
    public $person;

    /**
    * @var Form
    */
    private $form;

    public functionn __construct(Form $form)
    {
        $this->form = $form;
        // I have been logged in as a certain user
        $this->person = Yii::$app->user->identity->personData;
    }

    public function getForm()
    {
        $kind = $this->person->getPetSetting(Pets::TYPE_KIND)->one();

        $this->form->name = $this->person->name;
        $this->form->power = $this->person->power;
        $this->form->name = $kind = $kind ? $kind->kind : null;

        return $this->form;
    }

    public function processForm(Form $form)
    {
        $form->save();
    }
}

And last the models with the connections:

Class Code extends ActiveRecord implements IdentityInterface
{
    public function getPersonData()
    { 
        return $this->hasOne(Person::class, ['PersonId'=>'PersonID'])
    }
}
Class Person extends ActiveRecord implements IdentityInterface
{
    public function getPetSetting($type)
    { 
        return $this->hasOne(Pet::class, ['PersonId'=>'PersonID'])->andWhere(['type'=>$type])
    }
}

Now most of this works perfectly, But I can't get the process part to work. I have the form and I get the data, but when I change it, it won't change in the database and stay the same in the form.


Solution

  • You need to save the models in the processForm function:

     public function processForm(Form $form)
    {
        $model1 = new Model1();
        $model1->attribute1 = $this->attribute1;
        $model1->save();
    
        $model2 = new Model2();
        $model2->attribute2 = $this->attribute2;
        $model2->save();
    }
    

    The form itself has no knowledge on how to map the form fields to the models, so you need specify how to map the attributes.