Laravel リレーションでの値を取り出す時の記述と動作について
制作環境
Windows 10
Laravel : 6.18.35
Laravel/ui : 1.0
Laravel-mix : 5.0.1
Bootstrap : 4.0.0
MDBootstrap : 4.19.1
chart.js : 2.9.3
XAMPP
PHP : 7.4.3
Visual Studio Code
質問理由
Laravelを勉強中の初心者です。
リレーションを学ぶ為、簡易的なプログラムを作成しているのですが、動作と記述で疑問に思ったことがあるので質問をさせていただきます。
プログラムの内容
プログラムの内容は以下の通りで、あまり使用されない内容だとは思いますが、1対1のリレーションを想定してます。
動作確認が主な目的の為、デザイン等は考慮してません。
マイグレーションファイル
Items テーブルと Stocks テーブルを作成します。
public function up()
{
if (!Schema::hasTable('items')) {
Schema::create('items', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('name');
$table->timestamps();
});
}
}
public function up()
{
if (!Schema::hasTable('stocks')) {
Schema::create('stocks', function (Blueprint $table) {
$table->bigIncrements('id');
$table->unsignedBigInteger('item_id');
$table->foreign('item_id')->references('id')->on('items')->onDelete('cascade');
$table->string('stock');
$table->timestamps();
});
}
}
モデル
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasOne;
class Item extends Model
{
protected $fillable = ['name'];
public function stock(): HasOne
{
return $this->hasOne('App\Models\Stock');
}
}
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
class Stock extends Model
{
protected $fillable = ['stock'];
protected $primaryKey = 'item_id';
public function item(): BelongsTo
{
return $this->belongsTo('App\Models\Item')->withTimestamps();
}
}
コントローラ
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\Item;
class ItemController extends Controller
{
public function index()
{
$data = Item::with('stock')->get();
return view('item', compact('data'));
}
}
ルーティング
Route::get('/item', 'ItemController@index');
ビュー
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>リレーション</title>
</head>
<body>
<table>
<thead>
<tr>
<th>商品名</th>
<th>在庫数</th>
</tr>
</thead>
<tbody>
@foreach ($data as $item)
<tr>
<td>{{ $item->name }}</td>
<td>{{ $item->stock->stock }}</td>
</tr>
@endforeach
</tbody>
</table>
</body>
</html>
実際の表示
質問内容
質問したいのは、ビューの記述と動作についてです。
上では、値いを取り出すのに
@foreach ($data as $item)
<tr>
<td>{{ $item->name }}</td>
<td>{{ $item->stock->stock }}</td>
</tr>
@endforeach
と記述してますが、以下の記述でも同様に値を取り出すことができます。
@foreach ($data as $item)
<tr>
<td>{{ $item['name'] }}</td>
<td>{{ $item['stock']['stock'] }}</td>
</tr>
@endforeach
どちらの記述がよいのでしょうか?
また、$item->stock->stockはstockメソッドで、改めてリレーション先の値を取得しているという動作の認識なのですが、あってますでしょうか?
疑問に感じた理由
$item->stock->stockはstockメソッドで、改めてリレーション先の値を取得しているという認識でいるのですが、その場合このメソッドを使用するのは無駄ではないかと感じたからです。
dd($item) を使用し、値を確認したところ、
attributesとoriginalにリレーション元の値、
relationsにリレーション先の値があるのがわかります。
これは、コントローラで$data = Item::with('stock')->get()とし、両方の値を取得しているからだと思います。
そもそもコントローラで取得しているなら、改めてstock()メソッドで呼び出さなくてもいいのではないかと感じました。
この場合のstock()メソッドは改めて情報を取得しているのではなく、relationsから値を取得しているのでしょうか?
もし改めて取得しているなら、$item['stock']['stock']の方が処理が減るような気がします。
ご教授いただけたら幸いです。