У меня есть сущность с именем "Post":
/**
* @ORM\Entity(repositoryClass="App\Repository\PostRepository")
*/
class Post
{
/**
* @ORM\Id()
* @ORM\GeneratedValue()
* @ORM\Column(type="integer")
*/
private $id;
/**
* @ORM\Column(type="text", nullable=true)
*/
private $content;
/**
* @ORM\ManyToOne(targetEntity="UserSubscriptionTier", inversedBy="posts")
* @Assert\NotBlank()
*
*/
private $subscriptionTier;
... and all the various get/set functions
}
Итак, моя главная мысль здесь заключается в том, что $ subscriptionTier - это не объект коллекции, а просто атрибут одной сущности.
Вот как выглядит класс типа формы:
класс PostType расширяет AbstractType
{
/ **
* @var UserProvider
* /
защищенный $ userProvider;
public function __construct(UserProvider $userProvider)
{
$this->userProvider = $userProvider;
}
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('file', FileType::class, [
'label' => 'File or Files',
'required' => false,
'mapped' => false,
'multiple' => true,
'attr'=>array('style'=>'display:none;')
])
->add('content', TextareaType::class, [
'required' => false
])
->add('subscriptionTier', EntityType::class, [
'class' => UserSubscriptionTier::class,
'choices' => $this->userProvider->getCurrentUser()->getSubscriptionTiers(),
'choice_label' => 'name',
'required' => false,
'multiple' => true,
'expanded' => true
])
->add('save', SubmitType::class, array(
'attr' => array('class' => 'save')
))
;
}
Таким образом, subscriptionTier - это просто отдельный атрибут сущности с множеством вариантов для выбора.
Вот то, на что это похоже, когда я строю это в ветке, из входящей формы:
<select class="custom-select" name="subscriptions" required="required">
<option disabled selected>Visibility</option>
{% for key,val in postForm.subscriptionTier.vars.choices %}
{% if val.data.tierNumber == 1 %}
<option value="{{ val.value }}" {{ postForm.subscriptionTier.vars.value == '' and key == 0 ? ' selected ' :(val.value == postForm.subscriptionTier.vars.value ? ' selected ' : '') }}>All Subscribers</option>
{% endif %}
<option value="{{ val.value }}" {{ postForm.subscriptionTier.vars.value == '' and key == 0 ? ' selected ' :(val.value == postForm.subscriptionTier.vars.value ? ' selected ' : '') }}>{{ val.label | trans }}</option>
{% endfor %}
</select>
Вот код контроллера после отправки формы:
public function createPostAction(PostRepository $postRepository, Request $request)
{
$user = $this->getUser();
$subscriptionId = $request->request->get('subscriptions');
$userSubscriptionTier = $this->subscriptionTierRepository->find($subscriptionId);
$post = new Post();
$post->setUser($user);
$post->setSubscriptionTier($userSubscriptionTier);
$form = $this->createForm(PostType::class, $post);
Именно эта функция createForm вызывает следующую ошибку:
Unable to transform value for property path "subscriptionTier": Expected a Doctrine\Common\Collections\Collection object.
Почему Symfony ожидает объект коллекций для одного атрибута сущности? Разве выбор из нескольких вариантов в форме обманул Symfony в ожидании ArrayCollection?