質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.62%

formから複数のレコードを更新したい

解決済

回答 3

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 1,477

複数の<input>タグからフォームに送信を実行すると、最後に送信したデータの内容が全てのレコードに反映されてしまうという問題で困っています。
原因または解決策をご存知の方はいらっしゃいませんか。

私の行った手順は以下です。
(1)同一テーブルカラムの中にある複数のレコードに更新処理を掛けるFormの記述
(2)Controller側で受け取ったデータを「$a = 〇〇::where(‘id’, ‘=’, $request->id)->get();」という形で受け取り、foreachで展開。
(3)カラムごとに「$a->xx = $request->xx;」という形でRequestを受け取り、最後にsave()メソッドで更新。

すると、全てのレコードが最後に送信したデータの内容になってしまうという状況になりました。

私は【foreachで展開して、それぞれsaveをしているため、where(‘id’, ‘=’, $request->id)で各レコードが区別されて、それぞれレコードが対応したデータに更新する】と思いました。

原因を確かめるため、以下のようなテストを行ってみましたが、
問題の解決には至りませんでした。
(a) 入力を「$a = 〇〇::where(‘id’, ‘=’, $request->id)->first();」にし、foreachでの展開をやめてみた
→上記と同じく全てのレコードが最後に送信したデータの内容になってしまうという状況になった。
なお、私の環境は以下の通りです。
【MacBook Air (13-inch, Early 2015), 8 GB 1600 MHz DDR3,  AWS, Laravel5.8.21】

検索エンジンで「laravel レコード 複数挿入 form」などのキーワードを使用して検索しましたが、
formから受け取ったデータを複数挿入する方法などについては見つかりませんでした。

以下に該当コードを抜粋して記載いたしますので、何卒解決策やアドバイスをいただきますよう、よろしくお願いいたします。

●Controller

public function makeInvoice(Request $request, $invoiceId, $clientId)
     {
:
:
        $bills = Bill::where('invoice_id', '=', $request->bill_invoice_id)->get();
        foreach($bills as $bill){
        $bill->billing_item = $request->billing_item;
        $bill->unit = $request->unit;
        $bill->quantity = $request->quantity;
        $bill->bill_unit_price = $request->bill_unit_price;
        $bill->save();
        }
:
:
}


●blade(foreachで該当レコード分だけinputタグが出てくるようにしています。)

{{Form::open(['url' => route('makeInvoice',['clientId'=>$val->client_id, 'invoiceId' => $val->id]),'method'=>'POST', 'target'=>'_blank'])}}
    {{ csrf_field() }}
:
:
            <tr>
                <!--品番・品名-->
                <td>{{Form::text('billing_item', $val->billing_item,['class' => 'validate', 'id' => 'billing_item'])}}</td>
                <!--数量-->
                <td>{{Form::text('quantity', $val->quantity,['class' => 'validate', 'id' => 'quantity'])}}</td>
                <!--単位-->
                <td>{{Form::text('unit', $val->unit,['class' => 'validate', 'id' => 'unit'])}}</td>
                <!--単価-->
                <td>{{Form::text('bill_unit_price', ceil($val->bill_unit_price),['class' => 'validate', 'id' => 'bill_unit_price'])}}</td>
                <!--金額-->
                <td>{{$val->quantity * $val->bill_unit_price}}</td>
                <td><a href="#" data-id="{{$val->id}}" class="waves-effect waves-light btn del">削除</a>
                </td>
                {{Form::hidden('bill_invoice_id', $val->invoice_id)}}
            </tr>
:
:
  {{Form::close()}}

・・・追記
manualには、
name属性(例えばbilling_item)に対して[]を付ければ、
indexが数値として入るとのことでしたので、以下のようにbladeを変更しました。

@foreach($billList as $val)
            <tr>
                <!--品番・品名-->
                <td>{{Form::text('billing_item[]', $val->billing_item,['class' => 'validate', 'id' => 'billing_item'])}}</td>
                <!--数量-->
                <td>{{Form::text('quantity[]', $val->quantity,['class' => 'validate', 'id' => 'quantity'])}}</td>
                <!--単位-->
                <td>{{Form::text('unit[]', $val->unit,['class' => 'validate', 'id' => 'unit'])}}</td>
                <!--単価-->
                <td>{{Form::text('bill_unit_price[]', ceil($val->bill_unit_price),['class' => 'validate', 'id' => 'bill_unit_price'])}}</td>
                <!--金額-->
                <td>{{$val->quantity * $val->bill_unit_price}}</td>
                <td><a href="#" data-id="{{$val->id}}" class="waves-effect waves-light btn del">削除</a>
                </td>
                {{Form::hidden('bill_invoice_id', $val->invoice_id)}}
            </tr>
                <?php $subtotal += $val->bill_unit_price; ?>
                @endforeach

また、Controllerを以下のように変更しました。

        $bills = Bill::where('invoice_id', '=', $request->bill_invoice_id)->get();
        foreach($request->input("bills") as $id => $bill){
        $bill->billing_item = $request->billing_item;
        $bill->unit = $request->unit;
        $bill->quantity = $request->quantity;
        $bill->bill_unit_price = $request->bill_unit_price;
        $bill->save();
        }

しかし、ソースコードを確認するとarray[]の中が空欄となっていました。
イメージ説明

https://php.net/manual/ja/faq.html.php#faq.html.arraysについても参照したのですが、問題が分かりませんでした…。再度、助言いただけましたら幸いです。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 3

checkベストアンサー

0

formで複数のレコードを扱う場合は、form内のinputのnameを配列にしてあげると可能です。

#bills[id または index][properly]
name="bills[1][billing_item]"
name="bills[1][quantity]"


PHP HTML フォームで配列を使用するにはどうすればよいですか?

その後、リクエストデータをforeachで回すと良いです。

foreach($request->input("bills") as $id=>$bill){
//処理
}

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

まずはSQLのテーブル構成とサンプルデータをつくり
具体的などういったデータを元にどう更新したいかSQL文を作るところからですね

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

以下で想定通りの挙動を確認できました。ありがとうございました。

・Controller

   $i = 0;
   foreach($request->bill_id as $id){
       $bill = Bill::find($id);
       $bill->billing_item = $request->billing_item[$i];
       $bill->unit = $request->unit[$i];
       $bill->quantity = $request->quantity[$i];
       $bill->bill_unit_price = $request->bill_unit_price[$i];
       $bill->save();
       $i++;
   }

・Blade

   $i = 0;
   foreach($request->bill_id as $id){
       $bill = Bill::find($id);
       $bill->billing_item = $request->billing_item[$i];
       $bill->unit = $request->unit[$i];
       $bill->quantity = $request->quantity[$i];
       $bill->bill_unit_price = $request->bill_unit_price[$i];
       $bill->save();
       $i++;
   }

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.62%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る