How to create through relationship in Laravel?

Let’s say you have a Survey. The survey has questions and each survey question has answers.

We will have a form that creates the survey question and the answers at the same time.

Example

Survey: Dog Survey

Question: Which breed is your favorite?

Answers: A) Pitbull, B) Bulldog, C) Golden Retriever

The survey questions belong to the Survey and answers belong to the survey questions.

In your Laravel app, how would you create the relationships through each other?

Let’s start with the models.

Survey Model

The Survey will have many survey questions so it needs


// app/Survey.php

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Survey extends Model
{
    protected $guarded = [];

    public function questions()
    {
        return $this->hasMany('App\Question');
    }
}

Question Model

Each question belongs to a Survey and each question has many answers.


// app/Question.php

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Question extends Model
{
    protected $guarded = [];

    public function survey()
    {
        return $this->belongTo('App\Survey');
    }

    public function answers()
    {
        return $this->hasMany('App\Answer');
    }
}


Answer Model

Each answer belongs to a question


// app/Answer.php

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Answer extends Model
{
    protected $guarded = [];

    public function question()
    {
        return $this->belongsTo('App\Question');
    }
}

Migrations

This is how my migration file looks like: (stripped to only provide relevant information)


    public function up()
    {
        Schema::create('surveys', function (Blueprint $table) {
            $table->id();
            $table->string('title');
            $table->timestamps();
        });

        Schema::create('questions', function (Blueprint $table) {
            $table->id();
            $table->unsignedBigInteger('survey_id');
            $table->string('question');
            $table->timestamps();
            $table->foreign('survey_id')->references('id')->on('survey');
        });

        Schema::create('answers', function (Blueprint $table) {
            $table->id();
            $table->unsignedBigInteger('question_id');
            $table->string('answer');
            $table->timestamps();
            $table->foreign('question_id')->references('id')->on('questions')->onDelete('cascade');
        });
    }

Creating the Models through the relationships in Laravel

Finally, the important part. How will the store function look like when you submit the form? The store function needs to add the questions to the Survey and add the answers to the question.

In the web routes file, has a store route like this

Route::post('/survey/{survey}/questions', '[email protected]')

The store function would look like this. Keep in mind, I am not validating the data to keep the example short.


// In the QuestionController.php

public function store(Survey $survey, Request $request)
    {

        $question = $survey->questions()->create($request['question']);
        $answers = $question->answers()->createMany($request['answers']);

        return back();
    }

In the store function, we are creating the Question through the relationship with the Survey we get a Question object returned.

Then we create the many Answers through the Question model.


To summarize, we are using the methods provided by Eloquent to create the models through their relationships and inserting them into the Database.