假设我有两个实体:post
和comment
。每个post
可以有多个comments
。现在,假设我有一个评论表。应该接受用户输入并将其存储在数据库中。
简单的东西。至少应该如此,但我无法使其正常工作。
在创建评论(子级)时如何参考帖子(父级)?我尝试将post_id
手动传递给评论表单作为隐藏字段,但是收到了抱怨帖子ID是字符串的错误。
Expected argument of type "App\Entity\Post or null", "string" given.
CommentType.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,
]);
CommentController.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');
}
非常感谢您的帮助!
答案 0 :(得分:4)
您只需要传递实际的Post
实体,而不仅仅是ID。试试这个:
CommentController.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
}
答案 1 :(得分:1)
此代码对我有用:
CommentController.php
正如上面的flint所建议的,您只需要传递实际的Post实体,而不仅仅是id。然后,如果您遇到此错误template <typename MapLike, typename KeyLike>
void do_stuff(const MapLike & map, const KeyLike & key)
{
auto range = map.equal_range(key);
for (auto it = range.first; it != range.second; ++it)
// blah
}
,这是因为您需要在 new_comment 路线的路径中添加 post 条。 ParamConverter被隐式调用,它需要该段 {post} ,其名称与函数中用于 post 参数的名称相同。
"Unable to guess how to get a Doctrine instance from the request information for parameter "post"
PostController.php
/**
* @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');
}
CommentType.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()
]);
}
使用此方法,您无需删除两个表之间的Doctrine关系并手动设置ID。
答案 2 :(得分: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');
}
答案 3 :(得分:0)
错误消息说明了一切:
Expected argument of type "App\Entity\Post or null", "string" given.
如果转到注释实体(App \ Entity \ Comment),您会看到您的类将父帖子称为Post类(App \ Entity \ Post),而不是“ post_id”。
由ORM(在本例中为原则)在您的物理数据库和Entity类中进行链接,并在表中添加post_id字段。
这是ORM(对象关系模型)的用途。您不应再将Post和Comment视为Sql表,而应视为类(OOP)。
因此,我想添加与someParent相关的评论,我应该这样做:
$comment = new Comment();
$comment->setPost($post);
$ post是Post类的实例。