TL;DR
VALU Advent Calendar 2019の7日目の記事です。
今回はいつか使えるであろうLaravelの知見を列挙してみました。
モデルとマイグレーションファイルとresourceのあるコントローラーを同時に生成する
いつも新しいファイルの生成時に使うそれぞれのコマンドたち
$ php artisan make:migration create_posts_table
$ php artisan make:model Post
$ php artisan make:controller Post
実はこれらは1つのコマンド実行できる
$ php artisan make:model Post -mcr
m : モデル
c : コントローラー
r : resource
新しい機能を作る時などに試して欲しい
マイグレーションと同時にSeedingする
新しいマイグレーションファイルを作った時、ダミーデータでテストしたくなるのが常でしょう
しかし、dev環境などだとわざわざサーバーにssh接続してコマンドを打つのは面倒
そんな時、下記のようにマイグレーションファイルに追記すると、Seedingもできるようになります
public function up()
{
Schema::create('themes', function (Blueprint $table) {
$table->increments('id');
$table->text('name');
});
Artisan::call('db:seed', [
'--class' => ThemesTableSeeder::class
]);
}
productionでは動かないようにするのも忘れずに
public function up()
{
Schema::create('themes', function (Blueprint $table) {
$table->increments('id');
$table->text('name');
});
if (app()->environment() != 'production') {
Artisan::call('db:seed', [
'--class' => ThemesTableSeeder::class
]);
}
}
where
メソッドのTips
$users = User::where('approved', 1)->get();
whereメソッドはカラム名とつなげることもできます
$users = User::whereApproved(1)->get();
リレーションにおけるN+1問題の解決
親レコードのものをこのようにforeach文などで回して表示したい場合があるとします
@foreach ($sessions as $session)
<tr>
<td>{{ $session->created_at }}</td>
<td>{{ $session->user->name }}</td>
</tr>
@endforeach
リレーション内容
public function user()
{
return $this->belongsTo(User::class);
}
その時の間違ったコントローラーの書き方
public function index()
{
$sessions = Session::all();
return view('sessions.index', compact('sessions');
}
これだとSession
モデルのインスタンスを取得した後、ループが回るたびにUser
モデルのインスタンスを取得してしまい、表示数によっては負荷の大きい処理になってしまいます
そうならないための正しいコントローラーの書き方が以下になります
public function index()
{
$sessions = Session::with('user')->get();
return view('sessions.index', compact('sessions');
}
with
メソッドで事前にリレーション先のモデルのインスタンスを取得しておけば、ループで回したとしてもすでに取得したインスタンスを使うだけなので、処理がとても軽くなります
いわゆるEagerロードというやつですね
リレーション先が空の場合の表示
ユーザーネームがない匿名ユーザーなどの処理に使えます
bladeで処理する場合
{{ $payment->user->name ?? 'Anonymous' }}
それより前にEloquentで処理する場合
public function user()
{
return $this->belongsTo(User::class)
->withDefault(['name' => 'Anonymous']);
}
{{ $payment->user->name }}
簡略化したAuth::user()->id
ログイン中のユーザーIDが欲しい時にいつも使うであろうAuth::user()->id
しかし、こういう短い書き方もできます
Auth::id()
id
以外のプロパティも指定でき、ログアウト中はnull
になります