カテゴリ: Symfony 更新日: 2026/01/12

Symfonyでネストされたフォーム(CollectionType)を完全ガイド!初心者でもわかるフォーム処理入門

Symfonyでネストされたフォーム(CollectionType)を扱う方法
Symfonyでネストされたフォーム(CollectionType)を扱う方法

先生と生徒の会話形式で理解しよう

生徒

「Symfonyで親フォームの中に、複数の子フォームを入れたいのですが、どうやって作るのですか?例えば、ひとつの商品に複数のタグを付けるような入力欄です。」

先生

「Symfonyでは、CollectionTypeという仕組みを使うことで、親フォームの中に子フォームをいくつも入れられます。ネストされたフォームと呼ばれる機能ですね。」

生徒

「ネストってどういう意味なんですか?初心者の僕でも理解できますか?」

先生

「ネストとは“入れ子”という意味です。紙のアンケートで『商品の情報』の中に『タグを複数書く欄』があるようなイメージです。Symfonyでも同じように“フォームの中にフォームを入れる”ことができますよ。」

1. ネストされたフォームとは?

1. ネストされたフォームとは?
1. ネストされたフォームとは?

Symfonyのフォーム処理では、ひとつのフォームの内部に複数の入力欄のセットをまとめて扱うことができます。この仕組みをネストされたフォームと呼び、実現するための仕組みがCollectionTypeです。

例えば、ひとつの商品データ(親フォーム)の中に「複数のタグ」「複数の写真」「複数の住所」などを入力したい場合、ひとつずつのタグ入力欄(子フォーム)をまとめたCollectionTypeを使います。

紙の書類で例えると、商品の申込用紙(親フォーム)があり、その中に「タグを書き込む欄」が複数セットになっているイメージです。タグ欄は同じ形をしているため、CollectionTypeではそれをまとめて管理してくれます。

Symfony の検索キーワードとしては「Symfony CollectionType ネスト」「Symfony 子フォーム」「Symfony 複数入力」などがよく使われます。

2. CollectionTypeが必要になる場面を理解しよう

2. CollectionTypeが必要になる場面を理解しよう
2. CollectionTypeが必要になる場面を理解しよう

Symfonyのフォームを使って開発すると、次のような場面でCollectionTypeが役立ちます。

  • 複数のタグ入力欄をまとめて扱いたい
  • ユーザーが複数の電話番号を登録できるようにしたい
  • 商品に複数の写真を追加したい
  • アンケートで複数の選択肢を入力して保存したい

一般的なフォームでは単一の値を扱いますが、SymfonyのCollectionTypeでは「同じ形式の入力欄を繰り返し持てる」ため、柔軟なデータ構造を扱うことができます。

また、CollectionTypeはDoctrine ORMと連携することも多く、エンティティの中に配列やリストで関連するデータを保持しているケースでも便利です。

3. CollectionTypeを使ったフォーム構造の基本

3. CollectionTypeを使ったフォーム構造の基本
3. CollectionTypeを使ったフォーム構造の基本

ここでは、商品の中に複数のタグを登録する例を使って説明します。まずは、親エンティティと子エンティティの関係をイメージしましょう。

商品(Product)

  • 商品名
  • 価格
  • タグ(複数)

タグ(Tag)

  • タグ名

Symfonyのフォームでは、ProductType(親フォーム)にCollectionTypeを追加し、その中にTagType(子フォーム)を入れます。


$builder->add('tags', CollectionType::class, [
    'entry_type' => TagType::class,
    'allow_add' => true,
    'allow_delete' => true,
]);

entry_typeには「子フォームの型」を指定します。ここではTagTypeが子フォームに相当します。

allow_addは「タグを追加してよい」という許可、allow_deleteは「タグを削除してよい」という許可です。

紙の書類で例えると「追加入力欄を増やしてよい」「不要なら消してよい」というルールを設定しているようなイメージです。

4. 子フォーム(TagType)を作ってみよう

4. 子フォーム(TagType)を作ってみよう
4. 子フォーム(TagType)を作ってみよう

子フォームは、タグひとつ分の入力欄を定義します。Symfonyでは、独立したフォームタイプとして作成します。


$builder->add('name', TextType::class);

このTagTypeを親フォームのCollectionTypeに組み込むことで、親フォームからまとめて扱えるようになります。

子フォームが複数ある場合も同じように、このフォームクラスが繰り返し利用されます。

5. Twigテンプレートでネストされたフォームを描画しよう

5. Twigテンプレートでネストされたフォームを描画しよう
5. Twigテンプレートでネストされたフォームを描画しよう

フォームがネストされている場合、Twigでは親フォームの中で子フォームが自動的にレンダリングされます。


<div>
    {{ form_row(form.name) }}
</div>

<div>
    {{ form_row(form.tags) }}
</div>

CollectionTypeの場合、form.tagsの中にタグ入力欄が複数出力されます。

タグが3つあれば、3つ分のTagTypeがレンダリングされ、ユーザーは複数のタグを入力できるようになります。

6. CollectionTypeとDoctrineの連携の仕組み

6. CollectionTypeとDoctrineの連携の仕組み
6. CollectionTypeとDoctrineの連携の仕組み

Symfonyのフォーム処理では、Doctrine ORMと連携することで、ネストされたデータも自然な形でデータベースに保存できます。

親エンティティのProductに対して、Tagは「OneToMany」や「ManyToMany」などの関連を持ちます。この連携によって、フォームで入力されたタグが親エンティティに紐づいて保存されます。

紙の書類でたとえるなら、商品台帳(Product)と、その商品にひもづくタグ一覧(Tag)がセットで保存されるイメージです。

7. ネストされたフォームが動かないときの確認ポイント

7. ネストされたフォームが動かないときの確認ポイント
7. ネストされたフォームが動かないときの確認ポイント

7-1. 子フォームの設定が適切か確認する

子フォーム(TagType)に正しいフィールドが設定されていないと、親フォームから値が渡されません。

7-2. Doctrineの関連設定が正しいか確認する

エンティティ間の関連が正しく設定されていないと、データ保存時にエラーが発生することがあります。

7-3. CollectionTypeのオプションを確認する

allow_addallow_deleteが適切に設定されていなければ、新しい子フォームを追加しても保存されません。

Symfonyにおけるネストされたフォームは、最初は難しく見えるかもしれませんが、紙の台帳と追加入力欄の関係として考えると理解しやすくなります。

関連記事:
カテゴリの一覧へ
新着記事
New1
Laravel
Laravelの認証状態をチェックする方法を完全解説!authとAuth::check()を初心者向けにやさしく説明
New2
CodeIgniter
CodeIgniterのコントローラクラスの作り方を完全ガイド!初心者でもわかる基礎から実践まで
New3
Symfony
Symfonyのフォームラベルを多言語対応!初心者でもわかる翻訳設定ガイド
New4
Laravel
Laravelでユーザー登録機能を作る方法!初心者向けにバリデーションとリダイレクトをやさしく解説
人気記事
No.1
Java&Spring記事人気No1
Laravel
Laravelのデータベース設定方法を完全ガイド!初心者でもわかる.envファイルの使い方
No.2
Java&Spring記事人気No2
Laravel
Laravelのビューとは?Bladeテンプレートの基本を解説
No.3
Java&Spring記事人気No3
Laravel
Laravelでセッションを扱う方法!保存方法と利用例を解説
No.4
Java&Spring記事人気No4
Laravel
Laravelのルート一覧を確認する方法!初心者でもわかるphp artisan route:listの使い方
No.5
Java&Spring記事人気No5
Laravel
Laravelでルーティングを設定する方法!web.phpと基本ルートの書き方を初心者向けに徹底解説
No.6
Java&Spring記事人気No6
Laravel
LaravelでルートをBladeテンプレートに記述する方法(route関数)
No.7
Java&Spring記事人気No7
Laravel
Laravelでログを出力する方法(Monolog・storage/logs)
No.8
Java&Spring記事人気No8
Laravel
Laravelのルートキャッシュ機能を活用してパフォーマンス改善!初心者でもわかる完全ガイド