概要
EloquentにはfirstOrCreate()のように、データの取得と登録を同時に行うメソッドが存在しています。
そうしたメソッドを使用すると、データの存在チェックのためのif文を減らしたり、変数をnullで初期化して宣言する必要がなくなったりと、簡潔なコードを書くのに役立ちます。
今回はそうしたメソッドについて用途ごとにまとめてみました。
解説
DBにデータが存在する場合は取得し、存在しない場合はDBにデータを登録した上でインスタンスを取得する
この用途に合うメソッドがfirstOrCreate()です。
firstOrCreate()を使った場合、使わない場合、それぞれどのようになるか例を記載します。
firstOrCreate()を使わない場合
$post = Post::where('title', 'Eloquentのモデル生成について')
->first();
if (empty($post)) {
Post::create([
'user_id' => 1,
'content' => 'firstOrCreate()とは...',
'is_public' => true,
]);
}
firstOrCreate()を使った場合
それでは、firstOrCreate()を使うと上記のコードをどのように書き換えられるか、使用例を次に示します。
$post = Post::firstOrCreate([
'title' => 'Eloquentのモデル生成について'
], [
'user_id' => 1,
'content' => 'firstOrCreate()とは...',
'is_public' => true,
]);
第1引数には、検索条件のカラム名をキーとした連想配列を渡します。そして、第2引数の連想配列は、データが取得できなかった場合にDBに保存する際に使用されることになります。
そして、firstOrCreate()は、検索条件で取得した、もしくはDBに保存したモデルのインスタンスを返却します。
DBにデータが存在する場合は取得し、存在しない場合はインスタンスを取得する。但し、データは保存しない
この用途で使用するメソッドは、firstOrNew()です。
firstOrNew()を使わない場合
$post = Post::where('title', 'Eloquentのモデル生成について')
->first();
if (empty($post)) {
$post = new Post([
'user_id' => 1,
'content' => 'firstOrNew()とは...',
'is_public' => true,
]);
}
firstOrNew()を使った場合
$post = Post::firstOrNew([
'title' => 'Eloquentのモデル生成について'
], [
'user_id' => 1,
'content' => 'firstOrNew()とは...',
'is_public' => true,
]);
第1引数には、検索条件のカラム名をキーとした連想配列を渡します。そして、第2引数の連想配列は、データが取得できなかった場合に返却されるインスタンスのプロパティにセットされる値になります。
firstOrCreate()との違いは、データが見つからなかった場合でも、DBにデータを保存しないということです。
DBにデータが存在する場合はデータを更新し、存在しない場合は保存する
この用途で使用するメソッドはupdateOrCreate()です。
updateOrCreate()を使わない場合
$post = Post::where('title', 'Eloquentのモデル生成について')
->first();
if (empty($post)) {
$post = Post::create([
'user_id' => 1,
'content' => 'updateOrCreate()とは...',
'is_public' => true,
]);
} else {
$post->user_id = 1;
$post->content = 'updateOrCreate()とは...';
$post->is_public = true;
$post->save();
}
updateOrCreate()を使った場合
$post = Post::updateOrCreate([
'title' => 'Eloquentのモデル生成について'
], [
'user_id' => 1,
'content' => 'updateOrCreate()とは...',
'is_public' => false,
]);
第1引数には、検索条件のカラム名をキーとした連想配列を渡します。そして、第2引数には、更新 or 登録に使用するパラメータを連想配列で渡します。
第1引数の条件に該当するデータが存在する場合は更新し、存在しない場合は新規に作成します。
今回紹介したメソッドを使った場合、判定処理を書く必要が無くなっているのがわかるかと思います。
特にupdateOrCreate()を比較するとif~elseが無くなり、見やすくなりました。
この複合的な処理を行うメソッドは、tap()を使って実装されているのですが、それはまた別の記事で紹介したいと思います。
追記
tap()についての記事を作成しました!
