2016-02-26 2 views
3

Я на самом деле создаю очень простой REST Api, и у меня возникла проблема с этой важной функцией. Я попытался найти что-то полезное в документации Symfony, чтобы справиться с этой проблемой, но я не нашел ничего связанного с этим.Symfony form 2 разных типа значений в одном поле

Я хотел бы получить тело запроса, как это, например:

{ 
    "amount": "200", 
    "account": { 
     "name": "XXX XXXX", 
     "value": "asdasdasdasdasdsadsad" 
    } 
} 

Этот запрос будет создавать новый объект учетной записи и не сохраняются его (нет проблем с этим).

И некоторые другие времена, которые я хотел бы получить этот вид запроса

{ 
    "amount": "200", 
    "account": "e76ad9ea-dbc1-11e5-a764-109add42947b" 
} 

Идеи моего приложения является справиться с этим, связывающим новым объектом с предоставленным идентификатором счета (UUID).

EntityType.php

class EntityType extends AbstractType 
{ 
    /** 
    * @param FormBuilderInterface $builder 
    * @param array $options 
    */ 
    public function buildForm(FormBuilderInterface $builder, array $options) 
    { 
     $builder 
      ->add('amount') 
      ->add('account', AccountType::class); 
    } 

    /** 
    * @param OptionsResolver $resolver 
    */ 
    public function configureOptions(OptionsResolver $resolver) 
    { 
     $resolver->setDefaults(['data_class' => Entity::class, 'csrf_protection' => false]); 
    } 
} 

Юридическое лицо является довольно просто:

class Entity 
{ 
    /** 
    * @ORM\Column(type="guid") 
    * @ORM\Id 
    * 
    * @var string 
    */ 
    protected $id; 

    /** 
    * UUIDableEntity constructor. 
    */ 
    public function __construct() 
    { 
     $this->id = Uuid::uuid1()->toString(); 
    } 

    /** 
    * @return string 
    */ 
    public function getId(): string 
    { 
     return $this->id; 
    } 

    /** 
    * @var float 
    * 
    * @ORM\Column(type="float") 
    */ 
    protected $amount; 

    /** 
    * @var Account 
    * 
    * @ORM\ManyToOne(targetEntity="Account", cascade={"persist"}) 
    * @ORM\JoinColumn(referencedColumnName="id", nullable=false) 
    * @Assert\Valid() 
    */ 
    protected $account; 

    /** 
    * @return float 
    */ 
    public function getAmount() 
    { 
     return $this->amount; 
    } 

    /** 
    * @param float $amount 
    */ 
    public function setAmount(float $amount) 
    { 
     $this->amount = $amount; 
    } 

    /** 
    * @return Account 
    */ 
    public function getAccount() 
    { 
     return $this->account; 
    } 

    /** 
    * @param Account $account 
    */ 
    public function setAccount(Account $account) 
    { 
     $this->account = $account; 
    } 
} 

Я знаю одно решение может быть определить тип значения счета и использовать тип мне нужно (так что я потребуется два разных типа формы). Но это решение кажется мне грязным. Любые идеи по поводу реализации AccountType для ее обработки?

Реализация AccountType для создания нового объекта каждый раз достаточно проста, но не знаю, как я могу обрабатывать 2 разных типа значений запроса.

ответ

0

В этих ситуациях вам лучше обработать отображение самостоятельно, а не полагаться на поведение по умолчанию SF-форм. Я думаю, что вы могли бы достичь что-то подобное с помощью empty_data:

$resolver->setDefaults([ 
    'data_class' => 'Account::class', 
    'empty_data' => function (FormInterface $form) { 
     //on create 
     $account = new Account(
      $form->get('name')->getData(), 
      $form->get('value')->getData() 
     ); 

     //on update you'll need to inject the repo 
     $account = $this->accountRepository->findOne(
         $form->getData() 
        ); 

     return $account; 
    }, 
]); 

В соответствии с buildForm, что вам может понадобиться для генерации полей формы динамически. Вы можете сделать это, добавив eventListener для предварительной настройки ваших данных.

public function buildForm(FormBuilderInterface $builder, array $options) 
{ 
    $builder->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) { 
     $data = $event->getData(); 
     // check what data is coming in the request and add form fields accordingly 
     $form = $event->getForm(); 
     $form->add(...); 
    }); 

} 
+0

А как насчет buildForm? – Mauro

+0

Это не работает ... cos Мне нужно добавить имя и значение в функцию формы для извлечения этих данных из пустых_данных, и я не смогу обработать другое значение (без объекта, только ID) – Mauro

Смежные вопросы