Tech Starlog

Laravel リレーション(1対多)入門

投稿日:2026/01/11

Laravelで開発をしていると、必ず出てくるのがリレーション(関連)です。
最初は少し難しく感じますが、仕組み自体はとてもシンプルです。

この記事では、1対多(hasMany / belongsTo)を「注文と注文明細」の関係を例に解説します。


1対多とは?

1対多とは、1つのデータに対して、複数のデータが紐づく関係のことです。

ECサイトをイメージしてみましょう。

  • 注文(Order):1回の注文
  • 注文明細(OrderItem):注文内の商品情報

「1つの注文に、複数の注文明細が紐づく」
これが1対多の関係です。


テーブル構成

ordersテーブル(親)

orders
- id
- order_number
- total_price
- created_at

order_itemsテーブル(子)

order_items
- id
- order_id    ← 注文との紐づけ
- product_name
- price
- quantity

ポイントはorder_idです。
「どの注文の明細か」を示す外部キー


Model の定義

Orderモデル(1側)

class Order extends Model
{
    public function items()
    {
        return $this->hasMany(OrderItem::class);
    }
}

意味:

  • この注文は複数の注文明細を持つ

OrderItemモデル(多側)

class OrderItem extends Model
{
    public function order()
    {
        return $this->belongsTo(Order::class);
    }
}

意味:

  • この注文明細は1つの注文に属する

実際の使い方

注文から注文明細を取得する

$order = Order::find(1);

$items = $order->items;
  • この注文に含まれる商品一覧を取得できます。

注文明細から注文を取得する

$item = OrderItem::find(1);

$order = $item->order;
  • この明細が属している注文を取得できます。

なぜメソッド名は複数形 / 単数形?

Laravelの慣習です。

  • hasMany → 複数 → 複数形
  • belongsTo → 1つ → 単数形
$order->items;   // 複数
$item->order;   // 1つ

よくあるミス

外部キー(order_id)がない

order_items
- id
- product_name
- price
  • これだとどの注文の明細か分からないため、リレーションできません。

Model にリレーション定義を書いていない

テーブルを作っただけでは不十分です。

// Order モデルに hasMany
// OrderItem モデルに belongsTo
  • Modelに定義して初めて$order->itemsが使えるようになります。

まとめ

  • 1対多は実務で最もよく使うリレーション
  • 親:hasMany
  • 子:belongsTo
  • 外部キーが重要