Wakanda's avatar
Level 10

Has Many Create Form Correct Setp

Hi Devs,

I have a question and a question has many answers

answers table

Schema::create('answers', function (Blueprint $table) {
            $table->id();
            $table->text('body');
            $table->boolean('is_correct');
            $table->string('image')->nullable();
            $table->string('order')->nullable();
            $table->unsignedBigInteger('question_id');
            $table->timestamps();

            $table->foreign('question_id')->references('id')->on('questions')->onDelete('cascade');

            $table->index('question_id');
        });

Create Form

<div
            class="px-4 py-3 mb-8 bg-white rounded-lg shadow-md dark:bg-gray-800"
        >

            <label for="body" class="block mt-4 text-sm">
                <span class="text-gray-700 dark:text-gray-400">Question Body</span>
                <input type="hidden" name="question[body]" id="body"
                    class="block w-full mt-1 text-sm dark:text-gray-300 dark:border-gray-600 dark:bg-gray-700 form-textarea focus:border-purple-400 focus:outline-none focus:shadow-outline-purple dark:focus:shadow-outline-gray"
                    rows="3"
                    placeholder="Enter question body."
                    value="{{ isset($question) ? $question->body : old('body') }}"
                >
                <trix-editor input="body" class="dark:text-gray-300"></trix-editor>

                @error('question.body')
                    <span class="text-xs text-red-600 dark:text-red-400">
                        {{ $message }}
                    </span>
                @enderror
            </label>

            @if(isset($question) && $question->image != '')
                <div class="mt-3 form-group">
                    <img src="{{ asset($question->image) }}" class="w-1/3 h-44">
                </div>
            @endif

            <label class="block mt-4 text-sm">
                <span class="text-gray-700 dark:text-gray-400">Images (512 x 512px 720x 720 px, 1280 x 1280 px)</span>
                <div
                class="relative text-gray-500 focus-within:text-purple-600"
                >
                
                    <input type="file"  name="question[image]" id="image"
                    class="block w-full pr-20 mt-1 text-sm text-black dark:text-gray-300 dark:border-gray-600 dark:bg-gray-700 focus:border-purple-400 focus:outline-none focus:shadow-outline-purple dark:focus:shadow-outline-gray form-input"
                    placeholder="Image"
                    multiple
                    />

                    <button type="button" 
                    class="absolute inset-y-0 right-0 px-4 text-sm font-medium leading-5 text-white transition-colors duration-150 bg-purple-600 border border-transparent rounded-r-md active:bg-purple-600 hover:bg-purple-700 focus:outline-none focus:shadow-outline-purple"
                    >
                    Image Upload
                    </button>
                </div>

                @error('question[image]')
                <span class="text-xs text-red-600 dark:text-red-400">
                    {{ $message }}
                </span>
                @enderror
            </label>

            <!-- Question Answers Start -->
            <div class="mt-16 mb-16">

                <!-- Answer Block Start -->
                <div class="flex flex-wrap gap-6 mt-2">

                    <label class="w-1/2 text-sm">
                        <span class="text-gray-700 dark:text-gray-400">Answer Body</span>
                        <textarea type="text" name="answers[][body]" id="answer1" 
                            class="block w-full mt-1 text-sm dark:border-gray-600 dark:bg-gray-700 focus:border-purple-400 focus:outline-none focus:shadow-outline-purple dark:text-gray-300 dark:focus:shadow-outline-gray form-input"
                            placeholder="Enter choice 1"
                        /></textarea>
                    </label>
                    <label class="text-sm w-1/7">
                        <span class="text-gray-700 dark:text-gray-400">Ordering Answers</span>
                        <input type="text" name="answers[][order]" id="order1" 
                            class="block w-full mt-1 text-sm dark:border-gray-600 dark:bg-gray-700 focus:border-purple-400 focus:outline-none focus:shadow-outline-purple dark:text-gray-300 dark:focus:shadow-outline-gray form-input"
                            placeholder="A, B, C, D"
                            value="A"
                        />
                    </label>
                    <div class="mt-4 mr-2 -ml-1">
                        <div class="flex">
                            <label class="inline-flex items-center mt-3">
                                <input type="checkbox" name="answers[][is_correct]" id="is_correct1" class="w-5 h-5 text-green-600 form-checkbox">
                                <span class="ml-2 text-gray-700 dark:text-gray-300">Is Correct?</span>
                            </label>
                        </div>
                    </div>
                    
                </div>
                <label class="block mt-4 text-sm">
                    <span class="text-gray-700 dark:text-gray-400">Answer Image (512 x 512px 720x 720 px, 1280 x 1280 px)</span>
                    <div
                    class="relative text-gray-500 focus-within:text-purple-600"
                    >
                    
                        <input type="file"  name="answers[][image]" id="image"
                        class="block w-full pr-20 mt-1 text-sm text-black dark:text-gray-300 dark:border-gray-600 dark:bg-gray-700 focus:border-purple-400 focus:outline-none focus:shadow-outline-purple dark:focus:shadow-outline-gray form-input"
                        placeholder="Image"
                        multiple
                        />

                        <button type="button" 
                        class="absolute inset-y-0 right-0 px-4 text-sm font-medium leading-5 text-white transition-colors duration-150 bg-purple-600 border border-transparent rounded-r-md active:bg-purple-600 hover:bg-purple-700 focus:outline-none focus:shadow-outline-purple"
                        >
                        Image Upload
                        </button>
                    </div>

                    @error('answers.0.image')
                    <span class="text-xs text-red-600 dark:text-red-400">
                        {{ $message }}
                    </span>
                    @enderror
                </label>
                <!-- Answer Block End -->

                <!-- Answer Block Start -->
                <div class="flex flex-wrap gap-6 mt-2">

                    <label class="w-1/2 text-sm">
                        <span class="text-gray-700 dark:text-gray-400">Answer Body</span>
                        <textarea type="text" name="answers[][body]" id="answer2" 
                            class="block w-full mt-1 text-sm dark:border-gray-600 dark:bg-gray-700 focus:border-purple-400 focus:outline-none focus:shadow-outline-purple dark:text-gray-300 dark:focus:shadow-outline-gray form-input"
                            placeholder="Enter choice 2"
                        /></textarea>
                    </label>
                    <label class="text-sm w-1/7">
                        <span class="text-gray-700 dark:text-gray-400">Ordering Answers</span>
                        <input type="text" name="answers[][order]" id="order2" 
                            class="block w-full mt-1 text-sm dark:border-gray-600 dark:bg-gray-700 focus:border-purple-400 focus:outline-none focus:shadow-outline-purple dark:text-gray-300 dark:focus:shadow-outline-gray form-input"
                            placeholder="A, B, C, D"
                            value="B"
                        />
                    </label>
                    <div class="mt-4 mr-2 -ml-1">
                        <div class="flex">
                            <label class="inline-flex items-center mt-3">
                                <input type="checkbox" name="answers[][is_correct]" id="is_correct2" class="w-5 h-5 text-green-600 form-checkbox">
                                <span class="ml-2 text-gray-700 dark:text-gray-300">Is Correct?</span>
                            </label>
                        </div>
                    </div>
                    
                </div>
                <label class="block mt-4 text-sm">
                    <span class="text-gray-700 dark:text-gray-400">Answer Image (512 x 512px 720x 720 px, 1280 x 1280 px)</span>
                    <div
                    class="relative text-gray-500 focus-within:text-purple-600"
                    >
                    
                        <input type="file"  name="answers[][image]" id="image2"
                        class="block w-full pr-20 mt-1 text-sm text-black dark:text-gray-300 dark:border-gray-600 dark:bg-gray-700 focus:border-purple-400 focus:outline-none focus:shadow-outline-purple dark:focus:shadow-outline-gray form-input"
                        placeholder="Image"
                        multiple
                        />

                        <button type="button" 
                        class="absolute inset-y-0 right-0 px-4 text-sm font-medium leading-5 text-white transition-colors duration-150 bg-purple-600 border border-transparent rounded-r-md active:bg-purple-600 hover:bg-purple-700 focus:outline-none focus:shadow-outline-purple"
                        >
                        Image Upload
                        </button>
                    </div>

                    @error('answers.2.image')
                    <span class="text-xs text-red-600 dark:text-red-400">
                        {{ $message }}
                    </span>
                    @enderror
                </label>
                <!-- Answer Block End -->
            </div>
            <!-- Question Answers End -->

Controller

 public function store(Request $request, Practise $practise)
    {
        $question = $practise->questions()->create($request['question']);
        $question->answers()->createMany($request['answers']);
    }

Request DATA

  "question" => array:1 [▼
    "body" => "<div>Velit, quia esse ex .</div>"
  ]
  "answers" => array:4 [▼
    0 => array:1 [▼
      "body" => "Dolores aliqua A do"
    ]
    1 => array:1 [▼
      "order" => "Reiciendis mollitia"
    ]
    2 => array:1 [▼
      "body" => "Tenetur unde incidun"
    ]
    3 => array:1 [▼
      "order" => "Sit quaerat nisi qui"
    ]
  ]

The problem is when I create answers in this scenario I want to create one question and two answers instead am creating 4 answers instead of matching body and order to be of one answer and so on

Created answers collection

{
"body": "<div>Velit, quia esse ex .</div>",
"questionable_id": "99e461be-5cda-4499-a2c9-8264bc2a05e0",
"questionable_type": "App\Models\Practise",
"updated_at": "2021-09-25T17:03:43.000000Z",
"created_at": "2021-09-25T17:03:43.000000Z",
"id": 18,
"answers": [
{
"id": 19,
"body": "Dolores aliqua A do",
"is_correct": false,
"image": null,
"order": null,
"question_id": 18,
"created_at": "2021-09-25T17:03:43.000000Z",
"updated_at": "2021-09-25T17:03:43.000000Z"
},
{
"id": 20,
"body": null,
"is_correct": false,
"image": null,
"order": "Reiciendis mollitia",
"question_id": 18,
"created_at": "2021-09-25T17:03:43.000000Z",
"updated_at": "2021-09-25T17:03:43.000000Z"
},
{
"id": 21,
"body": "Tenetur unde incidun",
"is_correct": false,
"image": null,
"order": null,
"question_id": 18,
"created_at": "2021-09-25T17:03:43.000000Z",
"updated_at": "2021-09-25T17:03:43.000000Z"
},
{
"id": 22,
"body": null,
"is_correct": false,
"image": null,
"order": "Sit quaerat nisi qui",
"question_id": 18,
"created_at": "2021-09-25T17:03:43.000000Z",
"updated_at": "2021-09-25T17:03:43.000000Z"
}
]
}
0 likes
2 replies
tykus's avatar
tykus
Best Answer
Level 104

Put the index in the field name, e.g.

answers[1][body]
answers[1][order]

answers[2][body]
answers[2][order]

The Request will get body and order grouped together:

  "answers" => array:4 [▼
    0 => array:1 [▼
      "body" => "Dolores aliqua A do"
      "order" => "Reiciendis mollitia"
    ]
    1 => array:1 [▼
      "body" => "Tenetur unde incidun"
      "order" => "Sit quaerat nisi qui"
    ]
  ]

This will be in the correct format for a createMany method

1 like

Please or to participate in this conversation.