日々の開発、楽しんでいますか?
開発って、ちょっとした発見があったりして面白いですよね。
今回は、hasMany
リレーションの意外な使い方に出会って「そんなことできるの!?」と衝撃を受けたので、共有したいと思います。
hasMany は create にも使える
ズバリ、これです。
実は、Laravelの公式リファレンスにもちゃんと書いてあります。見落としている方も多いかもしれません。
🔗 公式ドキュメント – The create Method
これができると何が嬉しいか?
明細データのように「子テーブルに複数レコードを登録する」ケースで、記述がものすごくスッキリします。
親子データの登録がこんなにスマートに!
$parent->children()->createMany($children);
たったこれだけで、親に紐づく複数の子レコードを一括登録できます。
実例:食事記録アプリを作ってみよう
たとえば、食事記録アプリのように、1回の食事で複数のメニューを登録したい場面を考えてみましょう。
テーブルのリレーションは下図のようなイメージです。

モデルの定義
Meal モデル(親)
class Meal extends Model
{
use HasFactory;
protected $fillable = [
'consumed_at',
'meal_type',
'total_calories',
];
public function meal_items()
{
return $this->hasMany(MealItem::class, 'meal_id', 'id');
}
}
MealItem モデル(子)
class MealItem extends Model
{
use HasFactory;
protected $fillable = [
'meal_id',
'calories',
'item_name',
];
public function meal()
{
return $this->belongsTo(Meal::class, 'meal_id', 'id');
}
}
🔍 ポイント: MealItem
の belongsTo()
の引数は 'meal_id', 'id'
の順で指定するのが正しいです。
データ登録例
// 親データ登録
$meal = Meal::create([
'consumed_at' => '2025-06-06 07:30:00',
'meal_type' => 'breakfast',
'total_calories' => 473,
]);
// 子データ登録
$items = [
['item_name' => 'ご飯', 'calories' => 252],
['item_name' => '目玉焼き', 'calories' => 135],
['item_name' => 'グリーンサラダ', 'calories' => 25],
['item_name' => 'わかめと豆腐の味噌汁', 'calories' => 61],
];
$meal->meal_items()->createMany($items);
このように、シンプルなコードで「親 + 複数の子」をきれいに登録できます。


注意点:create() と createMany() の違い
- ✅ 単一レコード →
create([...])
- ❌ 複数レコード →
create([[...] , [...]])
はエラーになる - ✅ 複数レコード →
createMany([[...], [...], ...])
複数登録のときは、createMany()
を使う点に注意です。
まとめ
複雑な前処理やループを書かずに、Eloquentの機能だけでスッキリ記述できるのは大きなメリットです。
このように、データ加工と登録処理を分離して書けば、コードの可読性と保守性が大きく向上します。
Laravelが用意してくれている便利な機能は、積極的に活用していきましょう!