8

假设我有两个实体: apost和 a comment。每个post可以有很多comments。现在,假设我有一个评论表。它应该接受用户输入并将其存储在数据库中。

简单的东西。至少,它应该是,但我无法让它工作。

创建评论(子)时如何引用帖子(父)?我尝试手动将post_id评论表单作为隐藏字段传递,但收到一个错误,抱怨帖子 ID 是一个字符串。

Expected argument of type "App\Entity\Post or null", "string" given.

到目前为止,这是我的代码。有人可以将我推向正确的方向吗?

评论类型.php

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $post_id = $options['post_id'];

    $builder->add('content', TextareaType::class, [
        'constraints' => [
            new Assert\NotBlank(['message' => 'Your comment cannot be blank.']),
            new Assert\Length([
                'min'        => 10,
                'minMessage' => 'Your comment must be at least {{ limit }} characters long.',
            ]),
        ],
    ])->add('post', HiddenType::class, ['data' => $post_id]);
}

public function configureOptions(OptionsResolver $resolver)
{
    $resolver->setDefaults([
        'data_class' => Comment::class,
        'post_id' => NULL,
    ]);
}

PostController.php(这是评论表单出现的地方)

// Generate the comment form.
$comment = new Comment();
$form = $this->createForm(CommentType::class, $comment, [
    'action' => $this->generateUrl('new_comment'),
    'post_id'   => $post_id,
]);

评论控制器.php

/**
 * @param Request $request
 * @Route("/comment/new", name="new_comment")
 * @return
 */
public function new(Request $request, UserInterface $user)
{
    // 1) Build the form
    $comment = new Comment();
    $form = $this->createForm(CommentType::class, $comment);

    // 2) Handle the submit (will only happen on POST)
    $form->handleRequest($request);
    if ($form->isSubmitted() && $form->isValid())
    {
        // 3) Save the comment!
        $entityManager = $this->getDoctrine()->getManager();
        $entityManager->persist($comment);
        $entityManager->flush();
    }

    return $this->redirectToRoute('homepage');
}

非常感谢您的帮助!

4

4 回答 4

4

您只需要传递实际的Post实体,而不仅仅是 id。尝试这个:

评论控制器.php

public function new(Request $request, UserInterface $user, Post $post)
{
    // 1) Build the form
    $comment = new Comment();
    $comment->setPost($post); //where $post is instance of App\Entity\Post
    $form = $this->createForm(CommentType::class, $comment);

    // 2) Handle the submit (will only happen on POST)
    $form->handleRequest($request);
    if ($form->isSubmitted() && $form->isValid())
    {
        // 3) Save the comment!
        $entityManager = $this->getDoctrine()->getManager();
        $entityManager->persist($comment);
        $entityManager->flush();
    }

    return $this->redirectToRoute('homepage');
}

评论类型

public function buildForm(FormBuilderInterface $builder, array $options)
{
    //don't need to set the $post here

    $builder->add('content', TextareaType::class, [
        'constraints' => [
            new Assert\NotBlank(['message' => 'Your comment cannot be blank.']),
            new Assert\Length([
                'min'        => 10,
                'minMessage' => 'Your comment must be at least {{ limit }} characters long.',
            ]),
        ],
    ]);
}

public function configureOptions(OptionsResolver $resolver)
{
    $resolver->setDefaults([
        'data_class' => Comment::class
         //don't need the default here either
     ]);
}

评论实体

class Comment 
{
  /** 
  * @ORM\ManyToOne(targetEntity="App\Entity\Post")
  */
  private $post;

  //other vars

  public function setPost(\App\Entity\Post $post): void
  {
    $this->post = $post;
  }

  public function getPost(): \App\Entity\Post 
  {
     return $this->post;
  }

  //other functions
}
于 2018-11-05T03:33:53.843 回答
1

这段代码对我有用:

评论控制器.php

正如上面 flint 所建议的,您只需要传递实际的 Post 实体,而不仅仅是 id。然后,如果您遇到此错误"Unable to guess how to get a Doctrine instance from the request information for parameter "post",这是因为您需要在new_comment路由的路径中添加post slug 。ParamConverter 被隐式​​调用,它需要这个 slug {post}与您在函数中用于post参数的名称相同。

/**
 * @param Request $request
 * @return \Symfony\Component\HttpFoundation\RedirectResponse
 * @Route("/comment/new/{post}", name="new_comment")
 */
public function new(Request $request, Post $post)
{
    $comment = new Comment();
    $comment->setPost($post); //where $post is instance of App\Entity\Post
    $form = $this->createForm(CommentType::class, $comment);

    // 2) Handle the submit (will only happen on POST)
    $form->handleRequest($request);
    if ($form->isSubmitted() && $form->isValid())
    {
        // 3) Save the comment!
        $entityManager = $this->getDoctrine()->getManager();
        $entityManager->persist($comment);
        $entityManager->flush();
    }

    return $this->redirectToRoute('homepage');
}

PostController.php

/**
 * @Route("/post/{id}", name="get_post")
 */
public function getPostAction(Post $post)

{
    // Generate the comment form.
    $comment = new Comment();
    $form = $this->createForm(CommentType::class, $comment, [
        'action' => $this->generateUrl('new_comment', ['post' => $post->getId()]),
    ]);

    return $this->render('listeArticles.html.twig', [
        'form' => $form->createView()
    ]);

 }

评论类型.php

class CommentType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        //don't need to set the $post here

        $builder
            ->add('content', TextareaType::class, [
            'constraints' => [
                new Assert\NotBlank(['message' => 'Your comment cannot be blank.']),
                new Assert\Length([
                    'min'        => 10,
                    'minMessage' => 'Your comment must be at least {{ limit }} characters long.',
                ]),
            ],
        ])
        ->add('submit', SubmitType::class);
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults([
            'data_class' => Comment::class
        ]);
    }
}

有了这个,您不需要删除两个表之间的 Doctrine 关系并手动设置 ID。

于 2018-11-28T13:57:29.950 回答
0

不要放入表单字段,例如

public function new(Request $request, UserInterface $user)
{
    // 1) Build the form
    $comment = new Comment();
    $form = $this->createForm(CommentType::class, $comment);

    // 2) Handle the submit (will only happen on POST)
    $form->handleRequest($request);
    if ($form->isSubmitted() && $form->isValid())
    {
        comment->setPostId($post_id)
        $entityManager = $this->getDoctrine()->getManager();
        $entityManager->persist($comment);
        $entityManager->flush();
    }

    return $this->redirectToRoute('homepage');
}
于 2018-12-04T05:43:36.813 回答
0

错误消息说明了一切:

Expected argument of type "App\Entity\Post or null", "string" given.

如果您转到评论实体 (App\Entity\Comment),您会看到您的类将父帖子称为帖子类 (App\Entity\Post),而不是“post_id”。

是 ORM(在这种情况下为学说)在您的物理数据库和您的实体类中进行链接,并在您的表中添加一个 post_id 字段。

这就是 ORM(对象关系模型)的用途。您不应再将 Post 和 Comment 视为 Sql 表,而应视为类 (OOP)。

因此,我想添加与 someParent 相关的评论,我应该执行以下操作:

$comment = new Comment();
$comment->setPost($post);

其中 $post 是 Post 类的一个实例。

于 2018-12-04T12:11:04.333 回答