はじめての記事です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や色々な素敵機能があります。気が向くような事があれば、また書くかもしれません。)
それでは、ありがとうございました。