如何使用FOSRestBundle和symfony表单处理嵌套的json

时间:2016-01-09 06:03:58

标签: json symfony fosrestbundle

通过嵌套的json我的意思是将地址数据保存在自己的地址"地址"阵列:

{
  "user": {
    "id": 999,
    "username": "xxxx",
    "email": "xxxx@example.org",
    "address": {
      "street": "13th avenue",
      "place": 12
    }
  }
}

而不是平坦的

{
  "user": {
    "id": 999,
    "username": "xxxx",
    "email": "xxxx@example.org",
    "street": "13th avenue",
    "place": 12
  }
}

使用用户实体及其属性处理第一个平面there:" id","用户名"和"电子邮件"。使用symfony表单功能很好地验证了它:

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder->add('username');
    $builder->add('email', 'email');
    $builder->add('password', 'password');
    $builder->add('street');
    $builder->add('place');
}

我希望同时拥有" street"和"地点"作为User实体中的属性,使用doctrine将它们全部存储在数据库中的一个用户表中。但是我得到的json来自第三方,所以我无法修改它。

是否有任何构建表单的方法,因此它可以使用" address"来验证json。字段正确,仍然能够将所有用户数据保存在一个表中?

1 个答案:

答案 0 :(得分:2)

这是一个非常好的问题。想到的一个解决方案是使用表单事件手动创建未映射的表单和绑定数据,例如:

public function buildForm(FormBuilderInterface $builder, array $options)
{
    // Make a "nested" address form to resemble JSON structure
    $addressBuilder = $builder->create('address', 'form')
        ->add('place')
        ->add('street');

    $builder->add('username');
    $builder->add('email', 'email');
    $builder->add('password', 'password');
    // add that subform to main form, and make it unmapped
    // this will tell symfony not to bind any data to user object
    $builder->add($addressBuilder, null, ['mapped' => false]);

    // Once form is submitted, get data from address form
    // and set it on user object manually
    $builder->addEventListener(FormEvents::POST_SUBMIT, function (FormEvent $event) {
        $user = $event->getData();
        $addressData = $event->getForm()->get('address')->getData();

        $user->setStreet($addressData['street']);
        $user->setPlace($addressData['place']);
    })
}