Symfony 4 - 使用doctrine的一种形式的两个实体,一个实体必须在另一个实体之前插入

时间:2018-05-14 07:57:15

标签: php symfony

在组合两个实体时,我无法让textarea显示在我的表单中。没有javascript请,我已经看到了带有集合的javascript方法。

逻辑是,让用户在表单上添加标题,然后在textarea中添加文本。当用户提交时,使用标题输入一个线程,并使用线程ID向其添加帖子(textarea内容)。

表单示例:

enter image description here

如果通过2"类型"正确设置,我相信这足以输出它。类。

{{ form_start(forum_thread_form) }}
   {{ form_widget(forum_thread_form) }}
{{ form_end(forum_thread_form) }}

代码:

实体

Thread.php

     /**
     * @ORM\Id
     * @ORM\GeneratedValue
     * @ORM\Column(type="integer")
     */
    private $id;

    /**
     * @ORM\ManyToOne(targetEntity="App\Entity\Account", inversedBy="forum_posts")
     * @ORM\JoinColumn(nullable=false)
     */
    private $account;

    /**
     * @ORM\ManyToOne(targetEntity="App\Entity\Category", inversedBy="forum_threads")
     * @ORM\JoinColumn(nullable=false)
     */
    private $category;

    /**
     * @ORM\Column(type="string", length=128, nullable=true)
     * @Assert\NotBlank()
     */
    private $title;

    /**
     * @ORM\OneToMany(targetEntity="App\Entity\Post", mappedBy="thread")
     */
    private $posts;

    public function __construct()
    {
        $this->posts = new ArrayCollection();
    }

    ## getters and setters.. some ommitted ##
        /**

     /*
     * @return mixed
     */
    public function getPosts()
    {
        return $this->posts;
    }

    /**
     * @param mixed $posts
     */
    public function setPosts($posts): void
    {
        $this->posts = $posts;
    }

post.php中

    /**
     * @ORM\Id
     * @ORM\GeneratedValue
     * @ORM\Column(type="integer")
     */
    private $id;

    /**
     * @ORM\ManyToOne(targetEntity="App\Entity\Account", inversedBy="forum_posts")
     * @ORM\JoinColumn(nullable=false)
     */
    private $account;

    /**
     * @ORM\ManyToOne(targetEntity="App\Entity\Thread", inversedBy="posts")
     * @ORM\JoinColumn(nullable=true)
     */
    private $thread;

    /**
     * @ORM\Column(type="text")
     * @Assert\NotBlank()
     */
    private $content;

 ## GETTERS AND SETTERS, some ommitted ##
 /**
 * @return mixed
 */
public function getThread()
{
    return $this->thread;
}

/**
 * @param mixed $thread
 */
public function setThread($thread): void
{
    $this->thread = $thread;
}

/**
 * @return mixed
 */
public function getContent()
{
    return $this->content;
}

/**
 * @param mixed $content
 */
public function setContent($content): void
{
    $this->content = $content;
}

PostType.php

public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('content', TextareaType::class)
        ;
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => Post::class,
        ));
    }

ThreadType.php

public function __construct(){
        $this->posts = new ArrayCollection();
    }

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('title', TextType::class);

        $builder->add('content', CollectionType::class, array(
            'entry_type' => PostType::class,
            'entry_options' => array('label' => false),
        ));
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => Thread::class,
        ));
    }

ForumController.php

$forum_thread = new Thread();
$forum_thread_form = $this->createForm(ThreadType::class,$forum_thread);

        $forum_thread_form->handleRequest($request);

        if ($forum_thread_form->isSubmitted() && $forum_thread_form->isValid()) {
            $forum_thread = $forum_thread_form->getData();

            $entityManager = $this->getDoctrine()->getManager();
            $entityManager->persist($forum_thread);
            $entityManager->flush();

        }

        $forum_thread_form = $forum_thread_form->createView();

        return $this->render('forum/threads.html.twig',compact('forum_thread_form'));

3 个答案:

答案 0 :(得分:2)

首先在ThreadType中,将content更改为posts

$builder->add('posts', CollectionType::class, array(
        'entry_type' => PostType::class,
        'entry_options' => array('label' => false),
    ));

然后,更改操作中的代码:

$forum_thread = new Thread();
$post = new Post();
$forum_thread->setPosts([$post]);
$forum_thread_form = $this->createForm(ThreadType::class, $forum_thread);

$forum_thread_form->handleRequest($request);

if ($forum_thread_form->isSubmitted() && $forum_thread_form->isValid()) {
    $forum_thread = $forum_thread_form->getData();

    $entityManager = $this->getDoctrine()->getManager();
    $entityManager->persist($post);
    $entityManager->persist($forum_thread);
    $entityManager->flush();

}

这有效:

  • 创建新帖子
  • 添加仅包含新帖子的数组
  • getPosts用于使用新的PostType填充CollectionType的“posts”字段

答案 1 :(得分:1)

我只使用单一formtype + DTO来制作该表单,在提交+验证之后,只需从该DTO创建那些必要的实体,并将这些实体持久化并刷新到数据库。

答案 2 :(得分:0)

编辑你的树枝

{{ form_start(forum_thread_form) }}
   {{ form_row(forum_thread_form.title) }}
   {%  for contentField in forum_thread_form.posts %}
          {{ form_row(contentField.content) }}
   {%  endfor %}
{{ form_end(forum_thread_form) }}