0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

複数の値を一度に同じテーブルに入れる 【Laravel】

Posted at

## 複数の値を一度に同じテーブルに入れる【Laravel】

アンケートなどを作成するとき、一つの質問に対して、答えを複数用意したい。
そんな時のためのメモ。

環境:Laravel 8.50.0

まずはQuestionモデルとテーブル、Answerモデルとテーブルを作成。

Questionモデル


namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

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

    public function answers()
    {
        return $this->hasMany(Answer::class);
    }
}


questionsテーブル
    public function up()
    {
        Schema::create('questions', function (Blueprint $table) {
            $table->id();
            $table->string('question');
            $table->timestamps();
        });
    }

Answer モデル

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

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

    public function question()
    {
        return $this->belongsTo(Question::class);
    }
}

answersテーブル
    public function up()
    {
        Schema::create('answers', function (Blueprint $table) {
            $table->id();
            $table->foreignId('question_id')->constrained()->cascadeOnDelete();
            $table->string('answer');
            $table->timestamps();
        });
    }

web.php
Route::get('/questionnaires/{questionnaire}/question/create', [QuestionController::class, 'create'])->name('question.create');
Route::post('/questionnaires/{questionnaire}/questions', [QuestionController::class, 'store'])->name('question.store');
Route::get('/questionnaires/{questionnaire}', [QuestionnaireController::class, 'show'])->name('questionnaire.show');

question/create.blade
@extends('layouts.app')

@section('content')
    <div class="container">
        <div class="row justify-content-center">
            <div class="col-md-8">
                <div class="card">
                    <div class="card-header">Create New Question</div>

                    <div class="card-body">
                        <form action="{{ route('question.store', $questionnaire->id) }}" method="post">

                            @csrf

                            <div class="form-group">
                                <label for="question">Question</label>
                                <input name="question[question]" type="text" class="form-control"
                                    value="{{ old('question.question') }}" id="question" aria-describedby="questionHelp"
                                    placeholder="Enter Question">
                                <small id="questionHelp" class="form-text text-muted">Ask simple and to-the-point questions
                                    for best results.</small>

                                @error('question.question')
                                    <small class="text-danger">{{ $message }}</small>
                                @enderror
                            </div>

                            <div class="form-group">
                                <fieldset>
                                    <legend>Choices</legend>
                                    <small id="choicesHelp" class="form-text text-muted">Give choices that give you the most
                                        insight into your question.</small>

                                    <div>
                                        <div class="form-group">
                                            <label for="answer1">Choice 1</label>
                                            <input name="answers[][answer]" type="text"
                                                value="{{ old('answers.0.answer') }}" class="form-control" id="answer1"
                                                aria-describedby="choicesHelp" placeholder="Enter Choice 1">

                                            @error('answers.0.answer')
                                                <small class="text-danger">{{ $message }}</small>
                                            @enderror
                                        </div>
                                    </div>

                                    <div>
                                        <div class="form-group">
                                            <label for="answer2">Choice 2</label>
                                            <input name="answers[][answer]" type="text"
                                                value="{{ old('answers.1.answer') }}" class="form-control" id="answer2"
                                                aria-describedby="choicesHelp" placeholder="Enter Choice 2">

                                            @error('answers.1.answer')
                                                <small class="text-danger">{{ $message }}</small>
                                            @enderror
                                        </div>
                                    </div>

                                    <div>
                                        <div class="form-group">
                                            <label for="answer3">Choice 3</label>
                                            <input name="answers[][answer]" type="text"
                                                value="{{ old('answers.2.answer') }}" class="form-control" id="answer3"
                                                aria-describedby="choicesHelp" placeholder="Enter Choice 3">

                                            @error('answers.2.answer')
                                                <small class="text-danger">{{ $message }}</small>
                                            @enderror
                                        </div>
                                    </div>

                                    <div>
                                        <div class="form-group">
                                            <label for="answer4">Choice 4</label>
                                            <input name="answers[][answer]" type="text"
                                                value="{{ old('answers.3.answer') }}" class="form-control" id="answer4"
                                                aria-describedby="choicesHelp" placeholder="Enter Choice 4">

                                            @error('answers.3.answer')
                                                <small class="text-danger">{{ $message }}</small>
                                            @enderror
                                        </div>
                                    </div>

                                </fieldset>
                            </div>

                            <button type="submit" class="btn btn-primary">Add Question</button>

                        </form>
                    </div>
                </div>
            </div>
        </div>
    </div>
@endsection


細かく見てみます。

question

<div class="form-group">
<label for="question">Question</label>
//'question.question'で受け取る
<input name="question[question]" type="text" class="form-control"
value="{{ old('question.question') }}" id="question" aria-describedby="questionHelp"
placeholder="Enter Question">
<small id="questionHelp" class="form-text text-muted">Ask simple and to-the-point questions
for best results.</small>

@error('question.question')
<small class="text-danger">{{ $message }}</small>
@enderror
</div>

answer1

<div>
<div class="form-group">
<label for="answer1">Choice 1</label>
//answeresを配列で渡した1番目のanswer。answerがkey。
<input name="answers[][answer]" type="text"
//1番目なので0を指定 
value="{{ old('answers.0.answer') }}" class="form-control" id="answer1"
aria-describedby="choicesHelp" placeholder="Enter Choice 1">

@error('answers.0.answer')
<small class="text-danger">{{ $message }}</small>
@enderror
</div>
</div>

answer2,3,4も同じ。


QuestionController

class QuestionController extends Controller
{
    public function create(Questionnaire $questionnaire)
    {
       return view('question.create',compact('questionnaire'));
    }

    public function store(Questionnaire $questionnaire)
    {
        //Validationして$dataに入れる。
        $data = request()->validate([

            //question['question']
            'question.question' =>' required',
            //arrayを入力するのでワイルドカード
            'answers.*.answer' =>' required',
        ]);
          
        //$data['question']を作成
        $question = $questionnaire->questions()->create($data['question']);
        //$data['answers']を作成 answersは複数あるのでcreateMany
        $question->answers()->createMany($data['answers']);

        return redirect()->route('questionnaire.show',[$questionnaire->id]);
    }
}


QuestionnaireController

    public function show(Questionnaire $questionnaire)
    {
        //lazy loading.questionsと一緒にquestionsとリレーションを貼ったanswersを呼び出す。取得できる結果はwith(Eager)と同じ
        $questionnaire->load('questions.answers'); 
            
        return view('questionnaire.show',compact('questionnaire'));
    }

questionnaire/show.blade
//受け取った変数を$questionとしてループ
@foreach ($questionnaire->questions as $question)
  <div class="card mt-4">
    <div class="card-header">{{ $question->question }}</div>

  <div class="card-body">
     <ul class="list-group">
   //$questionとのリレーション$answersを$answerとしてループ
    @foreach ($question->answers as $answer)
       <li class="list-group-item">{{ $answer->answer }}</li>
    @endforeach
     </ul>
    </div>
  </div>
@endforeach

Question
Answer1
Answer2
Answer3
Answer4

と出力されます。



参考 https://youtu.be/_SyG3HMv48k
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?