0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

外部キー制約なしでも hasMany / belongsTo は使える?仕組みと注意点を解説

Last updated at Posted at 2025-03-27

はじめに

LaravelのEloquent ORMでは、hasManybelongsTo を使ってテーブル同士の親子関係(リレーション)を定義できます。

その際によく「外部キー制約が必要なのでは?」と思われがちですが、実は Eloquentは外部キー制約がなくてもリレーションが機能します。

今回はその仕組みと注意点を、自分の備忘録としてまとめます。


①外部キー制約なしでもリレーションは使える!

Eloquentの hasMany()belongsTo() は、あくまで 「モデル同士の紐付けルール(クエリの構築ルール)」 を定義しているだけです。

そのため、実際にデータベースに外部キー制約(FOREIGN KEY)がなくても機能します。


②具体例:User と Post のリレーション

posts テーブル(外部キー制約なし)

Schema::create('posts', function (Blueprint $table) {
    $table->id();
    $table->string('title');
    $table->unsignedBigInteger('user_id'); // 外部キー制約は付けない
    $table->timestamps();
});

モデル側の定義

// User.php
public function posts()
{
    return $this->hasMany(Post::class);
}

// Post.php
public function user()
{
    return $this->belongsTo(User::class);
}

このように定義しておけば、外部キー制約がなくても、$user->postsや$post->userは,
正しく機能します。

③なぜ動くのか?

Eloquentはリレーション定義をもとに、内部でSQLクエリを組み立てています。

例えば:

$post->user

は、実際には以下のようなクエリが実行されます:

select * form users where id = $post->user_id limit 1;

つまり、「user_idというカラムがある」ことが重要であって、DBに外部キー制約があるかどうかは関係ないということです。

④外部キー制約がなくてもよいのか?

結論から言うと、開発や学習環境ではOK!ですが、
本番環境では注意が必要です!

制約なしのメリット:

  • 柔軟に開発できる
  • 移行や変更が簡単(特にプロトタイプ段階)

制約なしのデメリット

  • 調合性が保証されない(存在しないpost_idをpostsに設定できてしまう)
  • 誤削除・参照エラーのリスク(ユーザー削除後にpostsが「孤立」することも)

⑤外部キー制約はつけるべき?

本番環境では以下のように、外部キー制約をつけることが推奨されます:

$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
  • データの整合性を保つ
  • Laravelのリレーションに加えて、DBレベルでも保証される

⑥まとめ

IMG_7732.jpeg

Laravelでは、リレーション=モデルの関係定義、外部キー制約=DBの安全ネット という意識で使い分けると理解しやすくなります!

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?