俺のLaravel
LaravelのTipsを書き溜めていく。
テクニック系
子でループせず孫の情報を直接取得したい
pluck メソッドと collapse メソッドを使用して、子のコレクションを取得し、それを一つのコレクションに結合することで、子の要素をループせずに孫の要素にアクセスすることができます。
孫の要素をユニーク化して取得
例)会社の社員の持ってる携帯種類を一覧化したいときとか
$company->staffs->pluck('phones')->collapse()->unique('type');
更新日時が最も新しい孫を1つ取得
$company->staffs->pluck('phones')->collapse()->sortByDesc('updated_at')->first();
バリデーションrequiredだけどnullableにしたい
present という便利なルールがあるのでこれを使う。
present自体は空を許容するが、他ルールとセットで使う場合はnullableも指定すればOK!
present|nullable|string
実行されたSQLを確認したい
方法1. dddで出力
webの場合お手軽で便利。
引数必要なので適当に ddd('a')
などでOK。
方法2. enableQueryLogを使う
確認したいSQLの前後に記述する
\DB::enableQueryLog();
処理
dd(\DB::getQueryLog());
方法3. toSqlを使う(laravel9の場合)
eloquentの関数。ワンライナーで書けてよさそう
dd($model->toSql(), $model->getBindings());
参考: https://codelikes.com/confirm-laravel-sql/#toc1
sortいろいろ
https://naoqoo2.github.io/20220314-【Laravel】リレーション先のテーブルでソートする.md
Resource内でSQL発行してないか確認する
N+1問題とか起きがち。
Controller
return new HogeResource(['fuga' => $fuga]);
↓
Controller
// return new HogeResource(['fuga' => $fuga]);
\DB::enableQueryLog();
new HogeResource(['fuga' => $fuga])->toArray($request);
print_r(\DB::getQueryLog());exit;
スラッシュを含むURLパラメータを取得したい
http〜/hoge/aa/bb/c.jpg?123
のとき aa/bb/c.jpg
の部分をパラメータとして取得したい。
誤)これだと404エラーになる
Route::get('hoge/{file_path}', 'HogeController@index');
正)whereで正規表現でスラッシュ含む形にしてあげればOK(?以降は含まれない)
Route::get('hoge/{file_path}', 'HogeController@index')->where('file_path', '(.*)');
ポリモーフィックリレーションでリレーション先のモデルが存在しないものは取得対象外にしたい
https://naoqoo2.github.io/20230726-ポリモーフィックリレーションでリレーション先のモデルが存在しないものは取得対象外にしたい.md
挙動注意系
ExistsバリデーションでEloquent使う際の落とし穴
eloquentを使うことでテーブル名を直接書かなくて済む
ただしexistsはeloquentのスコープ使えない
deleted_atも見ない
グローバルスコープも効かない
うーん。。
テストコード assertModelExists
idだけの比較で各カラムの値まではチェックしてくれない。。