Many To Many Relation In A Form

Hi,

I’m a new user of Yii framework and I decided to start with the Yii2 for my new php project.

I downloaded the advanced template because I need a backend area and a frontend area.

I created a database and the model related to this database. I have a model for a class named Questions, and a model for class Categories.

I created a backend form to create a new Question with Gii, but I need to show a check box list with all my categories and to link them to the new Question. This is a many to many relation: a question can have more than one category linked.

Do you have a link with an example? I cannot figure out how to link the data and extract the Categories items on the form.

Thank you very much!

use Multi Select widget populated with list of categories on successfull form submission the multiselect widget send array of selected categories before or after validation assign them as required.

Thank you Ahamed.

Do you have a site where I can find some code example for Yii framework?

In your Category model, create a method that will return all the categories.

backend/models/Category.php


public static function getCategories()

{

    return Category::find()->select(['id', 'name'])->all();

}

Then, in your QuestionController’s ‘Create’ action, pass the data over to view to be rendered:-

backend/controllers/QuestionController.php




use app\models\Category;

public function actionCreate()

{

    $model = new Question();


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

        return $this->redirect(['view', 'id' => $model->id]);

    } else {

        return $this->render('create', [

            'model' => $model,

            'categories' => Category::getCategories(),

        ]);

    }

}

Then in your create.php / _form.php, create your check boxes.

backend/views/question/_form.php


use yii\helpers\ArrayHelper;

<?= $form->field($model, 'categories')->checkboxlist(ArrayHelper::map($categories, 'id', 'name'));?> 

Do try understand how data / variables are passed to views and also understand that you need specify what classes you want to use in each model, controllers and views.

Thank you very much for your reply!

I think I’m very close to the solution…

Thanks to your advice I can see the form with all the categories I want, but if I check one or more category, it save correctly the question into table but not the ID into the relation table.

I checked the post array via


print_r(Yii::$app->request->post());

and I see the IDs I checked but when I do


$model->save()

it saves only the field of Question class… Sure I miss something, but I cannot see where…

This is the code of my Question Controller for create action:




public function actionCreate()

    {

        $model = new Domande;

        

  

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

            return $this->redirect(['view', 'id' => $model->ID]);

        } else {

            return $this->render('create', [

                'model' => $model,

                'categorie' => Categories::getAllCategories(),

            ]);

        }

    }



This is my _form.php




<?php $form = ActiveForm::begin(); 	?>


    <?= $form->field($model, 'qCategories')->checkBoxList(ArrayHelper::map($categories, 'ID', 'titolo')) ?>

    

    <?= $form->field($model, 'domanda')->textarea(['rows' => 3]) ?>


    <?= $form->field($model, 'commento')->textarea(['rows' => 3]) ?>

    


    <div class="form-group">

        <?= Html::submitButton($model->isNewRecord ? 'Create' : 'Update', ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?>

    </div>


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



When I create the question, I have no errors, but there are no record in the link table between question and categories…

Thanks again for your help!

Do you have a junction table for question and category (e.g. QuestionCategory)? If yes, then you should create a model for this junction table. Assuming that FOREIGN KEY and REFERENCES is properly defined in all your tables, you can do this with ease using the Gii tool and Gii will create all the relation for you.

Once you have created a model, you need to create a new instance of the junction table model and save the model in your QuestionController’s ‘Create’ action.

backend/controllers/QuestionController.php


public function actionCreate()

{

    $model = new Domande;


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

         //Loop through each selected category and save

         foreach ($_POST['Domande']['qCategories'] as $categoryId) {

             $questionCategory = new QuestionCategory; //instantiate new QuestionCategory model

             $questionCategory->questionId = $model->id;

             $questionCategory->categoryId = $categoryId;

             $questionCategory->save();

          }

         return $this->redirect(['view', 'id' => $model->ID]);

     } else {

         return $this->render('create', [

              'model' => $model,

              'categorie' => Categories::getAllCategories(),

         ]);

     }

}

Other points to think about; error handling. Again, do not forget to load the appropriate model classes in order to save it.

Thank you very much!

I don’t know why but I thought it creates the relation automatically… :rolleyes: :rolleyes: :rolleyes:

Now it works perfectly! Thank you again!