Как встроить коллекцию форм в Symfony?

1

У меня возникают некоторые проблемы при создании формы, в которую входит коллекция другого объекта.

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

Я следил за текущей документацией по Symfony, и на самом деле я могу вставлять оба объекта Recipe и Tag, но для объекта тега фактически вставлен только идентификатор.

Вот что я сделал до сих пор:

Форма рецепта:

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder
        ->add('name')
        ->add('recipe_tags', CollectionType::class, array(
            'entry_type' => TagsType::class,
            'allow_add' => true,
            'by_reference' => false,
        ));

}

Что добавляет форму collationType TagsType, которую она кодирует следующим образом:

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder->add('name');
}

Затем я создаю объект тега в контроллере заранее, поэтому у объекта рецепта есть тег по умолчанию, который будет обновляться после отправки формы.

    $recipe = new Recipe();
    $tag = new Tags();
    $tag->setName('tag1');
    $recipe->addRecipeTag($tag);
    $form = $this->get('form.factory')->createNamed(null, RecipeType::class, 
    $recipe);

И, наконец, Рецепт сущности с (я думаю, так) надлежащей информации:

/**
 * @var \Doctrine\Common\Collections\Collection
 *
 * @ORM\ManyToMany(targetEntity="Tags", inversedBy="idRecipe", cascade=
 {"persist"})
 * @ORM\JoinTable(name="recipe_tags",
 *   joinColumns={
 *     @ORM\JoinColumn(name="id_recipe", referencedColumnName="id_recipe")
 *   },
 *   inverseJoinColumns={
 *     @ORM\JoinColumn(name="id_tag", referencedColumnName="id_tag")
 *   }
 * )
 * @Groups({"recipe_detail"})
 *
 */
private $recipe_tags;

Я также добавил аннотацию с сохранением каскада, следуя документации. Вот способ добавления тегов.

/**
 * Add recipeTag
 *
 * @param \AppBundle\Entity\Tags $recipeTag
 *
 * @return Recipe
 */
public function addRecipeTag(\AppBundle\Entity\Tags $recipeTag)
{
    $this->recipe_tags[] = $recipeTag;

    return $this;
}

И это то, что я вставил в мою базу данных (это возвращение после запроса POST):

 {
"recipe": {
"idRecipe": 3671,
"name": "TagName#76232",
"description": null,
"duration": null,
"updatedAt": null,
"createdAt": null,
"active": null,
"image": null,
"portions": null,
"idCategory": null,
"createdBy": null,
"recipeTags": [
  {
    "idTag": 143,
    "name": null
  }
],
"recipeSteps": [],
"recipeIngredients": null

}}

Как вы можете видеть, рецепт добавлен в корне, но имя для тега, который я только что создал, не добавляется. Кроме того, сводная таблица recipe_tags не добавляет данные вообще.

Что я делаю не так?

РЕДАКТИРОВАТЬ:

Я думаю, что проблема заключалась в том, что я использовал одно и то же поле имени формы для обоих объектов. Теперь я изменил поле и появилась новая ошибка:

{
  "code": 400,
  "message": "Validation Failed",
  "errors": {
  "errors": [
    "This value is not valid."
   ],
  "children": {
    "name": [],
    "recipe_tags": {
      "children": [
        {
          "children": {
            "tag": []
        }
      }
    ]
  }
}

}}

И это параметры, которые я передаю с запросом POST:

{"name":"Recipe#2342"}
{"recipe_tags":"TagName#76232"}

Есть идеи? Спасибо.

  • 0
    Можете ли вы опубликовать полные объекты? Также: Работает ли это, если вы вручную (в коде) создаете рецепт и 2 тега, добавляете их в рецепт и сохраняете и очищаете?
  • 0
    @ccKep, я очистил кеш, и теперь данные правильно вставлены в сводную таблицу recipe_tags. Также, когда я вручную добавляю рецепт, имя тега вставляется, в то время как когда я делаю это, используя формы, оно все еще оставляет пустым поле имени тега ... Я думаю, это потому, что обе таблицы имеют одно и то же поле "имя", и это делает формы symfony сходят с ума ... я сейчас меняю это.
Теги:
forms

2 ответа

0
Лучший ответ

Я, наконец, решил проблему. Я не правильно передавал параметры POST. Вот как это должно быть сделано в случае, если форма предназначена для спокойного api:

{
    "recipe_form[name]":"recipeName",
    "recipe_form[recipe_tags][0][tag]":"tag1",
    "recipe_form[recipe_tags][1][tag]":"tag2",
    "recipe_form[recipe_tags][2][tag]":"tag3"
}

..и так далее. Я назвал форму, которая помогла мне понять, как это работает. Также нет необходимости создавать теги, а затем передавать их в форму, поэтому я могу создать столько меток, сколько захочу.

Это контроллер:

    $recipe = new Recipe();
    $form = $this->get('form.factory')->
                createNamed('recipe_form', RecipeType::class, $recipe);
    $form->handleRequest($request);

    if ($form->isValid() && $form->isSubmitted()) {
        $em = $this->getDoctrine()->getManager();
        $em->persist($recipe);
        $em->flush();
        return array("recipe" => $recipe);
    }

    return array(
        'form' => $form,
    );

И тогда классы formType:

public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
    ->add('name')
    ->add('recipe_tags', CollectionType::class, array(
        'entry_type' => TagsType::class,
        'allow_add' => true,
        'by_reference' => false,
    ));

 }

 public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder->add('tag');
}

Приветствия.

1

С помощью ManyToMany вы должны просто добавить поле EntityType только с multiple=true в RecipeType и все будет готово, если вы не хотите также создавать новые теги.

  • 0
    Я хочу создать новые теги

Ещё вопросы

Сообщество Overcoder
Наверх
Меню