WST87448735
@WST87448735

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

[Laravel] DBでの配列の使い方(動的に増えるフォーム)

解決したいこと

Laravel6においてレシピアプリを開発中です。
フォームは動的に増え、1つのレシピ(recipes)に対して何個でも材料(materials)を登録できるようにしたいです。

ご教授お願いいたします。

該当するソースコード

RecipeController.php
public function store(RecipeRequest $request)
    {
     
        $recipe = Recipe::create(
            [
                'user_id' => auth()->id(),
                'name' => $request->name,
                'category_id' => $request->category_id,
                'image' => $path,
                'process' => $request->process,
            ]);
            
            
         $recipe->materials()->createMany([
          [
              'name' => $request->input('material_name.*'),
              'recipe_id' => $recipe->id,
              'amount' => $request->input('amount.*'),
              'unit' => $request->input('unit.*'),
            ],
        ]);
create.php
<div class="form-group">
        <label>材料
            <input class="form-control" type="hidden" name="recipe_id" value="">
            <div class="materials">
            <input class="form-control" type="name" name="material_name[]" placeholder="材料名">
            <input class="form-control" name="amount[]" placeholder="分量">
            <select class="form-control" name="unit[]">
                @foreach($units as $unit)
                 <option value="{{ $unit->name }}">{{ $unit->name }}</option>
                @endforeach
            </select>    
            <input type="button" value="+" class="add pluralBtn">
            <input type="button" value="-" class="del pluralBtn">
           
            </div>
        </label>
    </div>
Material.php
<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Material extends Model
{
    protected $fillable = [
        'name','recipe_id','amount','unit',  
    ];
    
    public function recipe()
    {
        return $this->belongsTo('App/Recipe');
    }
    
    public function unit()
    {
        return $this->hasOne('App/Unit');
    }
}

materials.table.php
 public function up()
    {
        Schema::create('materials', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->unsignedBigInteger('recipe_id');
            $table->string('name');
            $table->string('amount');
            $table->string('unit');
            $table->timestamps();
            
            $table->foreign('recipe_id')->references('id')->on('recipes')->onDelete('cascade');
        });
    }

0

2Answer

回答ではないですが、ヒントを書いておきます。
フォームを動的に増やすということは材料を入力すると次の入力欄を表示するということでしょうか?
でしたら、vueなどのjavascriptを使う必要があると思います。
RegisterControllerで$recipe->materials()->createManyにするのではなく、
materialsモデルを作成して、recipe_idに作成したレシピのidを入れる方法が一般的かなと思います。

0Like

Comments

  1. @WST87448735

    Questioner

    ありがとうございます!
    <input type="button" value="+" class="add pluralBtn">
    <input type="button" value="-" class="del pluralBtn">
    こちらでボタンを押したら増えるようにしてます。

    Materialsをcreateしてそこで配列を作り、リレーションで結びつけるイメージでしょうか????
  2. そうですね。materialsをループさせて作成するのがいいと思います。
    $recipe->materials()->createManyでなくてもMaterial::create()でrecipe_idが同じならbelongstoManyでレシピモデルから具材モデルを取得できます。
  3. @WST87448735

    Questioner

    フォームを増やして送信しても1つしかDBに登録されず、nameもamountもunitもそれぞれ複数DBに登録する方法が分かりません( ノД`)
  4. 配列で送信してforeachでループすれば良いと思います。

1つのレシピ(recipes)に対して何個でも材料(materials)を登録できるようにしたいです。
ならレシピが1に対して、材料が多ということですよね?
なら1対多の関係ですね。
laravel 1対多
で調べたら解決できそうですね。

0Like

Comments

  1. @WST87448735

    Questioner

    回答ありがとうございます!
    リレーションはわかるんですが、従テーブルに複数のカラムがあってかつ動的に増えるというのが混乱しています。
    自分が難しく考えているだけでしょうか?
  2. foreachとかでパラメータを回せば保存できると思いますが。
    まずは、自分がやりたいことを実現するためにどうすればいいかを考えてコードを書いてみれば、徐々に正解に近づいていくんじゃないかと思いますよ。
    あとは固定観念に囚われないで、先人の知恵をネットで漁って、自分とほぼ同じことやってそうな記事見つけて真似してみるのがいいかと思います。

Your answer might help someone💌