LoginSignup
5
3

More than 5 years have passed since last update.

リレーションの貼られていないエンティティをくっつけたFormTypeを作る

Posted at

はじめての記事ですm(_ _)m

※ この記事はSymfony2.7を対象に書いています。バージョンが違う場合は適宜補完してください。

SymfonyのFormTypeって便利ですよね。
使い方を知っていればたくさん楽できますよね。
知っていなければ苦労してゴチャゴチャのソースが出来ちゃったりします。

ということで、今回はSymfonyのFormTypeについて少し書いてみます。
(直にソース書いたので、コピペしても動かない可能性がアリマス)

SymfonyのFormTypeはModelとの連携がしやすく、更新処理などの大部分をお任せすることが可能です。

SymfonyのFormTypeはリレーションの貼ってある構造を理解し、勝手にGetterSetterだとかしてくれます。

基本的な形↓

リレーションを貼っているエンティティの場合


        // モデル
    class Person {
        public $personName;

        @ORM\OneToOne(targetEntity="Skill") 
        public $skill;
    }

    class Skill {
        public $skillName;

        /* @ORM\OneToOne(targetEntity="Person") */
        public $person;
    }

        // フォーム
    class PersonType extends AbstractType {
        public function buildForm(FormBuilderInterface $builder, array $options) {
            $builder
                ->add('personName')
                ->add('skill', new SkillType())
        }
    }

    class SkillType extends AbstractType {
        public function buildForm(FormBuilderInterface $builder, array $options) {
            $builder->add('skillName')
        }

        public function configureOptions(OptionsResolver $resolver) {
            $resolver->setDefaults(array(
                'data_class' => '..\Skill'
            ));
        }
    }

        // Controller
    class MyController extends Controller {
        // ここでフォームを作成
        public function indexAction() {
            $this->createForm(new PersonType(), new Person())
        }
    }

上記のようにリレーションが貼られている場合は

Personal(親)

Skill(子供)

という構造でFormTypeを作成することにより、いい感じになります。

では、PersonalとSkillというModelにリレーションが貼られていない場合どうすればいいでしょう。


$this->createForm(new PersonType(), new Person())
$this->createForm(new SkillType(), new Skill())

の用に2つFormTypeを作ってゴチャゴチャやるのでしょうか・・・?

実はそんな事をする必要はありません。

かんたんに言うと2つのFormTypeをまとめるFormTypeを作ればいいのです。

┌─────────親─────────┐
Personal(子供)         Skill(子供) 

とりあえずソース

リレーションを貼っていないエンティティの場合


        // Model
    // リレーションが貼られていない
    class Person {
        public $personName;
    }

    class Skill {
        public $skillName;
    }

        // Form
    // PersonとSkillをまとめるクラス
    class ParentType extends AbstractType {
        public function buildForm(FormBuilderInterface     $builder, array $options) {
            $builder
                ->add('person', new PersonType())
                ->add('skill', new SkillType());
        }
    }

    class PersonType extends AbstractType {
        public function buildForm(FormBuilderInterface     $builder, array $options) {
            $builder->add('personName');
        }

        public function configureOptions(OptionsResolver $resolver) {
            $resolver->setDefaults(array(
                'data_class' => '..\Person'
            ));
        }
    }

    class SkillType extends AbstractType {
        public function buildForm(FormBuilderInterface $builder, array $options) {
            $builder->add('skillName')
        }

        public function configureOptions(OptionsResolver $resolver) {
            $resolver->setDefaults(array(
                'data_class' => '..\Skill'
            ));
        }
    }

        // Controller
    class MyController extends Controller {
        // ここでフォームを作成
        public function indexAction() {
                        // 親モデルを作成
            $model = [
                'person' => new Person(),
                'skill' => new Skill(),
            ];

            $this->createForm(new ParentType(), $model)
        }
    }

上記のような形をとることで、全く関係のないFormTypeをまとめる事ができます。

こうすることにより、複数のFormTypeというインスタンスを作成することなく一括で管理でき、ソースもすっきりします。

FormTypeは基本的にはarray構造を、optionsのdata_classを設定している場合は、そのクラスをもとにという風になっています。

FormTypeは一見複雑に見えるかもしれませんが、構造に関しては簡単で、理解すると汎用性の高い部品だというのが分かるはずです。

(ほかにもFormTypeにはEventListenerや色々な素敵機能があります。気が向くような事があれば、また書くかもしれません。)

それでは、ありがとうございました。

5
3
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
5
3