🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

Laravel

LaravelとはTaylor Otwellによって開発された、オープンソースなPHPフレームワークです。Laravelはシンプルで表現的なシンタックスを持ち合わせており、ウェブアプリケーション開発の手助けをしてくれます。

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

Q&A

解決済

1回答

2305閲覧

Creating default object from empty value エラー解決したい

ttt---aaa

総合スコア21

MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

Laravel

LaravelとはTaylor Otwellによって開発された、オープンソースなPHPフレームワークです。Laravelはシンプルで表現的なシンタックスを持ち合わせており、ウェブアプリケーション開発の手助けをしてくれます。

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

0グッド

0クリップ

投稿2021/02/12 02:04

編集2021/02/12 06:40

やりたいこと

既存DB情報の更新処理を行う際に、見出しのエラーが発生し解決できずにいますので何かアドバイスをお願いいたします。
イメージ説明
イメージ説明
内容としては2つのテーブル(employeesテーブル、goodsテーブル)を一度に更新するものです。goodテーブルの情報が渡っていない(null?)が故のエラーなのでしょうか?
調べても見出せずにいますので何卒宜しくお願いいたします。

__Laravel バージョン 6.20.8
__

EmployeesController.php

<?php namespace App\Http\Controllers; use Illuminate\Http\Request; use App\Employee; use App\Goods; class EmployeesController extends Controller public function update(Request $request, $id) { $employee = Employee::find($id); $employee->office = $request->office; $employee->save(); $goods = Goods::find($id); $goods->uniform = $request->uniform; $goods->winter_clothes = $request->winter_clothes; $goods->shoes = $request->shoes; $goods->other = $request->other; $goods->memo = $request->memo; $goods->save(); return view('employee_show', compact('employee')); }

employee_edit.blade.php

@extends('layouts.app') @section('content') <div class="container"> <div class="login-container"> <h3>{{ $employee->employee_name }}({{ $employee->employee_id }})</h3> <div class="card-body"> <form method="POST" action="{{ route('employee_create.update', $employee->id) }}"> @csrf @method('PATCH') <div class="form-group row"> <label class="col-md-4 col-form-label text-md-right">所属事業所</label> <div class="col-md-6"> <select name="office" class="form-control"> <option value='disabled' style='display:none'></option> @foreach(['群馬営業所, '長野営業所'] as $office) <option @if ($employee->office === $office) selected @endif >{{ $office }}</option> @endforeach </select> </div> </div> @foreach($employee->goods as $goods) <div class="form-group row"> <label class="col-md-4 col-form-label text-md-right">制服</label> <div class="col-md-6"> <select name="uniform" class="form-control"> <option value='disabled' style='display:none'></option> @foreach(['S', 'M', 'L', 'XL'] as $size) <option @if ($goods->uniform === $size) selected @endif >{{ $size }}</option> @endforeach </select> </div> </div> <div class="form-group row"> <label class="col-md-4 col-form-label text-md-right">防寒着</label> <div class="col-md-6"> <select name="winter_clothes" class="form-control"> <option value='disabled' style='display:none'></option> @foreach(['S', 'M', 'L', 'XL'] as $size) <option @if ($goods->winter_clothes === $size) selected @endif >{{ $size }}</option> @endforeach </select> </div> </div> <div class="form-group row"> <label class="col-md-4 col-form-label text-md-right">靴</label> <div class="col-md-6"> <select name="shoes" class="form-control"> <option value='disabled' style='display:none'></option> @foreach(['23㎝', '23.5㎝', '24㎝', '24.5㎝', '25㎝', '25.5㎝', '26㎝', '26.5㎝', '27㎝', '27.5㎝', '28㎝', '28.5㎝'] as $size) <option @if ($goods->shoes === $size) selected @endif >{{ $size }}</option> @endforeach </select> </div> </div> <div class="form-group row"> <label class="col-md-4 col-form-label text-md-right">その他</label> <div class="col-md-6"> <input type="text" name="other" class="form-control" value="{{ $goods->other }}" placeholder="その他を入力してください"> </div> </div> <div class="form-group row"> <label class="col-md-4 col-form-label text-md-right">メモ</label> <div class="col-md-6"> <input type="text" name="memo" class="form-control" value="{{ $goods->memo }}" placeholder="メモを入力してください"> </div> </div> @endforeach <div class="form-group row mb-0"> <div class="col-md-8 offset-md-4"> <input type="submit" value="社員情報を更新する" class="btn btn-primary"> <input type="reset" value="戻る" class="btn btn-secondary" onclick='window.history.back(-1);'> </div> </div> </form> </div> </div> </div> @endsection

Employee.php

<?php namespace App; use IlluminateSupportFacadesDB; use Illuminate\Database\Eloquent\Model; class Employee extends Model { protected $fillable = ['id','emlpoyee_id','employee_name','office']; public function goods() { return $this->hasMany(Goods::class); } }

Goods.php

<?php namespace App; use Illuminate\Database\Eloquent\Model; class Goods extends Model { protected $fillable = ['employee_id','uniform','winter_clothes','shoes','other','memo']; protected $guarded = array('id'); public function getDate() { return $this->belongsTo(Employee::class); } public function employee() { return $this->belongsTo(Employee::class); } }

解決した詳細

EmployeesController.php

<?php namespace App\Http\Controllers; use Illuminate\Http\Request; use App\Employee; use App\Goods; class EmployeesController extends Controller public function update(Request $request, $id) { $employee = Employee::find($id); $employee->office = $request->office; $employee->save(); $goods = $employee->goods()->latest()->first();//(修正後) //(修正前)$goods = Goods::find($id); $goods->uniform = $request->uniform; $goods->winter_clothes = $request->winter_clothes; $goods->shoes = $request->shoes; $goods->other = $request->other; $goods->memo = $request->memo; $goods->save(); return view('employee_show', compact('employee')); }

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Lulucom

2021/02/12 02:42

EmployeeとGoodsの関係(1対1 or 1対多 ?)、Laravelのバージョンも質問に追記されると良いでしょう。
ttt---aaa

2021/02/12 02:54

Lulucomさん コメントありがとうございます。モデルとLaravelのバージョンについて追記しました。
Lulucom

2021/02/12 03:06

EmployeeとGoodsの関係は1対多なんですね。複数のGoodsの中から、更新対象となる1つのGoodsを、どのように選別すれば良いでしょうか。
ttt---aaa

2021/02/12 03:38

現状、EmployeeとGoodsの関係は1対1で完結しておりますが、更にgoodsの各個数などのテーブルを足そうと1対多にしておりました。 恐れ入りますが、知識が疎いため、以下についてお教えいただければと思います。 ■更新対象の選別については外部キーで「id」を繋げば選別できているものだと思っているのですが、認識が間違ってますでしょうか? ■先にご回答いただいたものについて、 「$idにはEmployeeのidの値が渡ってきているので、その$idでGoodsを取得することはできません。」→$idではない別の変数を設定して、goods情報を取得させる旨の認識であっていますのでしょうか?
Lulucom

2021/02/12 04:33

(回答の方へコメントいたしました)
guest

回答1

0

ベストアンサー

updateメソッドの $goods = Goods::find($id);(74行目)で取得できず、$goodsがnullになっているのだと思います。

$idにはEmployeeのidの値が渡ってきているので、その$idでGoodsを取得することはできません。

(追記)

例えば、以下のような感じにするとどうでしょうか。
フォームから goods[0][uniform] のような name で送信させると、
アクションでは $request->goods で配列として受け取れるはずですので、その配列を処理すれば良さそうです。

employee_edit.blade.php

blade

1 @foreach($employee->goods as $i => $goods) 2 <input type="hidden" name="goods[{{ $i }}][id]" value="{{ $goods->id }}"> 3 ... 4 <select name="goods[{{ $i }}][uniform]" ... > ... </select> 5 ... 6 <select name="goods[{{ $i }}][winter_clothes]" ... > ... </select> 7 ... 8 <select name="goods[{{ $i }}][shoes]" ... > ... </select> 9 ... 10 <input type="text" name="goods[{{ $i }}][other]" ... > 11 ... 12 <input type="text" name="goods[{{ $i }}][memo]" ... > 13 ... 14 @endforeach

EmployeesController.php

php

1 public function update(Request $request, $id) 2 { 3 // Employeeの更新 4 $employee = Employee::find($id); 5 $employee->office = $request->office; 6 $employee->save(); 7 8 // Goodsの更新 9 foreach ($request->goods as $goods) { 10 $employee->goods()->updateOrCreate([ 11 'id' => $goods['id'], 12 ], $goods); 13 } 14 15 // 更新後はリダイレクト 16 return redirect()->route( ... ); 17 }

参考: updateOrCreate

投稿2021/02/12 02:32

編集2021/02/12 09:16
Lulucom

総合スコア1899

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Lulucom

2021/02/12 05:05 編集

> 更新対象の選別については外部キーで「id」を繋げば選別できているものだと思っているのですが、認識が間違ってますでしょうか? 外部キーはgoods.employee_idであり、これはemployees.idと繋がっていると思います。 1対多にする場合「1人のEmployeeに紐づくGoodsが複数ある」という意味になります。そのため、この質問のような画面では、何らかの条件に基づいて、その従業員に紐づく複数のGoodsの中から1つのGoodsを選別する必要があると思っています。 仕様をよくわかっておりませんが、例えば、作成日時が最新のもの、などの条件で良いのでしょうか?(全然違いますか?) > →$idではない別の変数を設定して、goods情報を取得させる旨の認識であっていますのでしょうか? 前述の「何らかの条件」に基づいて取得することになるかと思います。 例えば、作成日時が最新のものという条件でしたら、次のような感じでしょうか。 $goods = $employee->goods()->latest()->first(); // この従業員に紐づくGoodsを最新順に並べた最初のものを取得
ttt---aaa

2021/02/12 05:12

外部キーの件については理解しました。 やりたいこととしては、社員(employee)とその社員が貸与されているもの(goods)を紐づかせているので、更新(update)ページにて、 2つのテーブルを情報を書き換え登録をできるものにしたいと考えています。現状、社員(employee)情報のみは値が入っていると思いますが、貸与品(goods)にも値を入れるにはどうようにしたら良いものでしょうか? $goods = $employee->goods()->latest()->first(); // 所有するGoodsを最新順に並べた最初のものを取得 →これは、Goodsインスタンスを生成し$goodsへ代入後の記述になるのでしょうか?(わかりづらくて申し訳ございません)
Lulucom

2021/02/12 05:42 編集

いいえ、掲載されたエラー画面にEmployeesController.phpの一部が写っていますが、その行数で言うと、64行目と74行目が正しくなさそうなので、それらの行を次のように変更するとどうでしょうか。 // この従業員への貸与品を最新順に並べた最初のものを取得 $goods = $employee->goods()->latest()->first(); (最新順に並べた最初のもの、という条件で良いのかはよくわかっていませんが・・・)
Lulucom

2021/02/12 05:46

よく見たら64行目の$goodsはビューに渡されていないので使われていないようですね。64行目自体は不要だと思います。すみません。
ttt---aaa

2021/02/12 06:35

64行目削除しても問題なく動きました(ありがとうございます!)。 74行目の箇所を$goods = $employee->goods()->latest()->first();にしたところ実装したいことができました! 上記の件で公式ドキュメントを拝見しても、ぼんやりしているため更に質問をお願いします... ■64行目自体は不要について →モデルで外部キーを紐づけているため、新たにGoodsインスタンスの生成は不要ということでしょうか? ■$goods = $employee->goods()->latest()->first();について、それぞれ下記認識でよろしかったでしょうか? ①$employee->goods() →外部キーで繋いでいるため、上記コードでgoodsテーブルを引き出せることが可能 ②latest()->first(); →latestメソッドにより、goodsデータを整列し、firstメソッドにより要素を取得している
Lulucom

2021/02/12 07:21 編集

> 外部キーで繋いでいるため、上記コードでgoodsテーブルを引き出せることが可能 そのとおりです。$employee->goods() はgoodsテーブルのレコードに対してSQLの WHERE employee_id = 従業員のid を指定しているイメージです。 > latestメソッドにより、goodsデータを整列し、firstメソッドにより要素を取得している latest()はorderBy('created_at', 'desc')と同様です。 first()は最初のレコードを取得します。 > モデルで外部キーを紐づけているため、新たにGoodsインスタンスの生成は不要ということでしょうか? そのとおりです。既に紐づいているのを取得すれば良いです。Bladeの以下の箇所で取得していますね。 @foreach($employee->goods as $goods) Bladeをよく見たら、1つのGoodsに絞り込んでいるわけではなく、紐づいたGoodsすべてをforeachで表示していたんですね。それを見落としていました、すいません。その場合、フォームからの送り方と、アクションでの受け取り方を少し変更した方が良さそうですので、あとで回答に追記しておきます。(今のままでも動くとは思います)
ttt---aaa

2021/02/12 07:30

質問の件、理解できました。ありがとうございます! フォームからの送り方などの件、とても気になりますので大変お手数ですが、引き続きご教示をお願いいたします…
ttt---aaa

2021/02/13 00:15

返信が遅くなり申し訳ございません。 nameの指定やforeachの仕様について、こういった使い方もあるのですね!また、updateOrCreateメソッドについても初めて拝見し勉強になります。動いていても不要なものがあるかどうかは見ていただかないと気付けいないことがたくさんあるので非常に勉強になります。この度は細かなところまでご教示いただきありがとうございました!
Lulucom

2021/02/13 00:45

追記したコードは、きちんと動作確認をしたわけではないので参考程度にしていただければと思います。既存の実績あるコードを参考にしたので、ほぼ問題無いと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問