Symfony Doctrine ORMのリレーションを完全ガイド!初心者でもわかるOneToOne・OneToManyの使い方
生徒
「SymfonyのDoctrine ORMでデータ同士をつなげるリレーションってどうやって定義するんですか?」
先生
「リレーションとは、データ同士の関係性を表す仕組みのことで、Symfonyではとてもよく使う重要な概念なんだよ。」
生徒
「OneToOneとかOneToManyという言葉は聞いたことがありますが、具体的にどういう意味なんでしょう?」
先生
「それでは、初心者でもわかるように、身近なたとえを使いながら丁寧に説明していこう。」
1. Doctrine ORMのリレーションとは?
SymfonyのDoctrine ORMでいうリレーションとは、エンティティ同士のつながりのことです。データベースには多くのテーブルがあり、そのテーブル同士がどのように関係しているかを表す仕組みが必要です。
初心者向けに例えると、リレーションは「家族や友達関係」のようなものです。ひとりの人がひとつの家と結びついていたり、複数の友達とつながっていたりするように、データ同士にもさまざまな関係があります。
Doctrineではこの関係をアノテーション(@OneToOneなど)を使って定義することで、データの関連付けを簡単に扱えるようになります。
2. OneToOneリレーションとは?
OneToOne(1対1)とは、ひとつのデータに対して、ひとつだけ関連するデータが存在する関係です。たとえば、「ユーザー」とその「プロフィール」は1対1の関係で結びつけられます。
日常の例で言うと、「ひとりの人にひとつのパスポートが発行される」ようなイメージです。
■ OneToOneのサンプルコード
#[ORM\OneToOne(targetEntity: Profile::class, cascade: ['persist'])]
private $profile;
このコードは「UserエンティティはProfileエンティティと1対1で結びついている」という意味です。cascadeのpersistは「Userを保存したときProfileも保存する」という設定です。
3. OneToMany / ManyToOneリレーションとは?
OneToMany(1対多)とは、ひとつのデータに対して複数の関連データが存在する関係です。逆に、ManyToOne(多対1)は複数のデータがひとつのデータに紐づく関係を指します。
日常生活で例えると、「学校のクラスと生徒」の関係がわかりやすいです。 ・ひとつのクラスに複数の生徒が所属 → OneToMany ・生徒は必ずひとつのクラスに所属 → ManyToOne
■ OneToMany / ManyToOneのサンプルコード
#[ORM\OneToMany(mappedBy: 'classRoom', targetEntity: Student::class)]
private $students;
#[ORM\ManyToOne(targetEntity: ClassRoom::class, inversedBy: 'students')]
private $classRoom;
上記のコードでは、ClassRoomは複数のStudentを持ち、StudentはひとつのClassRoomに所属するという関係が定義されています。「mappedBy」は反対側のプロパティの名前を指定する役割があります。
4. ManyToManyリレーションとは?
ManyToMany(多対多)は、複数のデータが複数のデータに紐づく複雑な関係です。たとえば「生徒とクラブ活動」が典型的です。
日常の例: ・複数の生徒が複数のクラブに参加できる ・クラブも複数の生徒を持てる これが多対多の関係です。
■ ManyToManyのサンプルコード
#[ORM\ManyToMany(targetEntity: Club::class)]
private $clubs;
多対多では中間テーブルが自動で生成されるため、データベース設計を意識しなくても扱いやすくなっています。
5. Doctrineリレーションでよくある疑問と注意点
Doctrine ORMでリレーションを扱うと、「どちら側で設定すればいいのか」「mappedBy/inversedByの違い」「cascadeの使い方」など、最初は複雑に感じる部分もあります。
初心者向けにポイントを整理すると次のとおりです。
● mappedByとは?
「相手側で定義しているプロパティの名前」です。OneToMany側に設定します。
● inversedByとは?
「このリレーションを反対側から参照するときのプロパティ」です。ManyToOne側に設定します。
● cascadeとは?
関連データを一緒に保存・削除する設定で、初心者がよくつまずく部分です。
Doctrineはこれらの関係を自動で処理してくれるため、Symfonyではエンティティ同士のつながりを直感的に扱うことができます。