【Laravel】Trying to get property フィールド名 of non-objectについて

以下のサンプルにてPHPUnitを行いました。
そこで発生したエラーとその解決法についてです。

<ul>
	@foreach ($data as $item)
		<li>{{ $item->name }}[{{ $item->mail }}, {{ $item->age }}]</li>
	@endforeach
</ul>

<form action="/hello" method="post">
@csrf
	<p>ID: <input type="text" id="id" name="id"></p>
	<input type="submit">
</form>
Route::get('/hello','HelloController@index')->name('hello');
Route::post('/hello','HelloController@send')->name('hello');
public function index()
{
	$result = [];
	$data = [
		'msg' => 'This is Vue.js application',
		'data' => $result
	];

	return view('hello/index', $data);
}

public function send(Request $request)
{
	$id = $request->input('id');
	$person = Person::find($id);
	
	$data = [
		'msg'  => 'id=' . $id,
		'data' => [$person],
	];
	return view('hello.index',$data);
}

これで次の

$this->post('/hello')->assertOk();

を通すと
「Response status code [500] does not match expected 200 status code.」
というエラーがでます。

logを見てみると
「Trying to get property ‘name’ of non-object」
というエラーがでています。

Eloquentのモデルを利用していると起きることがあるんですが、どこでエラーが出ているかというと、

<li>{{ $item->name }}[{{ $item->mail }}, {{ $item->age }}]</li>

ここです。

このエラーの意味するところは、端的に言うと、そんなプロパティねーよ、てことですかね。
というか、このままpostしたらそりゃ中身nullですよね。

まぁとりあえずこの解決法は次のヘルパを使います。

optional()

先程のコードを以下のように直します。

<li>{{ optional($item)->name }}[{{ optional($item)->mail }}, {{ optional($item)->age }}]</li>

するとあら不思議、phpunitテスト通っちゃいます。

これは渡されたオブジェクトに対し、is_objectが真であればオブジェクトとプロパティを渡し、null時の例外を回避します。

ということで、なんか有名なヘルパ関数みたいですね。
・・・知らなかった・・・

コメントを残す

名前、メールアドレスは任意です。メールアドレスが公開されることはありません。

内容をご確認の上、送信してください。