无法在 Symfony 中创建新答案
Unable to create new answer in Symfony
我正在用 Symfony 制作一个应用程序。我得到相关的实体答案和问题。我想让用户能够添加问题的答案,但我遇到了将 question_id 获取到 AnswerEntity 的问题。
这是我想出的:
回答控制器
<?php
/**
* Answer Controller
*/
namespace App\Controller;
use App\Entity\Answer;
use App\Entity\Question;
use App\Form\AnswerType;
use App\Repository\AnswerRepository;
use App\Repository\QuestionRepository;
use Symfony\Component\Form\Extension\Core\Type\FormType;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Knp\Component\Pager\PaginatorInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Flex\PackageFilter;
use Symfony\Component\Routing\Annotation\Route;
/**
* Class AnswerController.
*
* @Route("/answer")
*/
class AnswerController extends AbstractController
{
private $answerRepository;
private $answer;
private $paginator;
/**
* AnswerController constructor
*
* @param \App\Repository\AnswerRepository $answerRepository Answer Repository
* @param \Knp\Component\Pager\PaginatorInterface $paginator
*/
public function __construct(AnswerRepository $answerRepository, PaginatorInterface $paginator)
{
$this->answerRepository = $answerRepository;
$this->paginator = $paginator;
}
/**
* Index action.
*
* @param \Symfony\Component\HttpFoundation\Request $request HTTP request
* @return \Symfony\Component\HttpFoundation\Response HTTP response
*
* @Route(
* "/",
* methods={"GET"},
* name="answer_index",
* )
*/
public function index(Request $request, PaginatorInterface $paginator, AnswerRepository $answerRepository): Response
{
$pagination = $paginator->paginate(
$answerRepository->queryAll(),
$request->query->getInt('page', 1),
AnswerRepository::PAGINATOR_ITEMS_PER_PAGE
);
return $this->render(
'answer/index.html.twig',
['pagination' => $pagination]
);
}
/**
* Create action.
*
* @param \Symfony\Component\HttpFoundation\Request $request HTTP request
*
* @param \App\Repository\AnswerRepository $answerRepository Answer repository
*
* @return \Symfony\Component\HttpFoundation\Response HTTP response
*
* @throws \Doctrine\ORM\ORMException
* @throws \Doctrine\ORM\OptimisticLockException
*
* @Route(
* "/create",
* methods={"GET", "POST"},
* name="answer_create",
* )
*/
public function create(Request $request, AnswerRepository $answerRepository): Response
{
$answer = new Answer();
$form = $this->createForm(AnswerType::class, $answer);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$answer->setQuestion($this->getQuestion());
$answerRepository->save($answer);
$this->addFlash('success', 'answer_created_successfully');
return $this->redirectToRoute('answer_index');
}
return $this->render(
'answer/create.html.twig',
['form' => $form->createView()]
);
}
}
答案表:
<?php
/**
* Answer type.
*/
namespace App\Form;
use App\Entity\Answer;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\EmailType;
use Symfony\Component\Form\Extension\Core\Type\HiddenType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
/**
* Class AnswerType.
*/
class AnswerType extends AbstractType
{
/**
* Builds the form.
*
* This method is called for each type in the hierarchy starting from the
* top most type. Type extensions can further modify the form.
*
* @see FormTypeExtensionInterface::buildForm()
*
* @param \Symfony\Component\Form\FormBuilderInterface $builder The form builder
* @param array $options The options
*/
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$builder->add(
'AnswerText',
TextType::class,
[
'label' => 'label_answertext',
'required' => true,
'attr' => ['max_length' => 200],
]
);
$builder->add(
'Nick',
TextType::class,
[
'label' => 'label_nick',
'required' => true,
'attr' => ['max_length' => 64],
]
);
$builder->add(
'Email',
EmailType::class,
[
'label' => 'label_email',
'required' => true,
'attr' => ['max_length' => 64],
]
);
$builder->add('is_best', HiddenType::class, [
'data' => '0',
]);
}
/**
* Configures the options for this type.
*
* @param \Symfony\Component\OptionsResolver\OptionsResolver $resolver The resolver for the options
*/
public function configureOptions(OptionsResolver $resolver): void
{
$resolver->setDefaults(['data_class' => Answer::class]);
}
/**
* Returns the prefix of the template block name for this type.
*
* The block prefix defaults to the underscored short class name with
* the "Type" suffix removed (e.g. "UserProfileType" => "user_profile").
*
* @return string The prefix of the template block name
*/
public function getBlockPrefix(): string
{
return 'answer';
}
}
和 AnswerEntity
<?php
namespace App\Entity;
use App\Repository\AnswerRepository;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity(repositoryClass=AnswerRepository::class)
* @ORM\Table(name="answers")
*/
class Answer
{
/**
* @ORM\Id
* @ORM\GeneratedValue
* @ORM\Column(type="integer")
*/
private $id;
/**
* @ORM\Column(type="string", length=200)
*/
private $answer_text;
/**
* @ORM\ManyToOne(targetEntity=Question::class, inversedBy="answer")
* @ORM\JoinColumn(nullable=false)
*/
private $question;
/**
* @ORM\Column(type="string", length=64)
*/
private $email;
/**
* @ORM\Column(type="string", length=64)
*/
private $Nick;
/**
* @ORM\Column(type="integer")
*/
private $isBest;
public function getId(): ?int
{
return $this->id;
}
public function getAnswerText(): ?string
{
return $this->answer_text;
}
public function setAnswerText(string $answer_text): void
{
$this->answer_text = $answer_text;
}
public function getQuestion(): ?Question
{
return $this->question;
}
public function setQuestion(?Question $question): void
{
$this->question = $question;
}
public function getEmail(): ?string
{
return $this->email;
}
public function setEmail(string $email): self
{
$this->email = $email;
return $this;
}
public function getNick(): ?string
{
return $this->Nick;
}
public function setNick(string $Nick): self
{
$this->Nick = $Nick;
return $this;
}
public function getIsBest(): ?int
{
return $this->isBest;
}
public function setIsBest(int $isBest): self
{
$this->isBest = $isBest;
return $this;
}
}
错误是:
[在此处输入图片描述][1]
[1]: https://i.stack.imgur.com/fYGpo.png
但我在 AnswerEntity 中有一个 getQuestion 函数,为什么它不读取它?它读取与实体相同的函数 setQuestion。
有没有机会换一种方式?
另外,我在到达 create_answer
的地方添加了部分问题模板代码
<a href="{{ url('answer_create', {id: questions.id}) }}" title="{{ 'create_answer'|trans }}">
{{ 'create_answer'|trans }}
</a>
答案在您发布的错误图像中,控制器中没有 $this->getQuestion()
,除非您创建该功能。
您可以使用 Doctrine 通过任何标识符获取问题实体
$question = this->getDoctrine()->getRepository(Question::class)->find($question_id);
然后你可以在你的$answer
对象中设置问题关系
$answer->setQuestion($question);
为什么你的路线中没有 questionId。我认为这是了解用户试图回答哪个问题的强制性数据。
在路由中使用请求参数 id
并在方法参数中键入 Question
ParamConverter
可以在您的控制器方法中注入正确的问题
/**
* ...
* @Route(
* "/create/{id}",
* methods={"GET", "POST"},
* name="answer_create",
* )
*/
public function create(Request $request, AnswerRepository $answerRepository, Question $question): Response
{
$answer = new Answer();
$answer->setQuestion($question);
// ....
我正在用 Symfony 制作一个应用程序。我得到相关的实体答案和问题。我想让用户能够添加问题的答案,但我遇到了将 question_id 获取到 AnswerEntity 的问题。 这是我想出的: 回答控制器
<?php
/**
* Answer Controller
*/
namespace App\Controller;
use App\Entity\Answer;
use App\Entity\Question;
use App\Form\AnswerType;
use App\Repository\AnswerRepository;
use App\Repository\QuestionRepository;
use Symfony\Component\Form\Extension\Core\Type\FormType;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Knp\Component\Pager\PaginatorInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Flex\PackageFilter;
use Symfony\Component\Routing\Annotation\Route;
/**
* Class AnswerController.
*
* @Route("/answer")
*/
class AnswerController extends AbstractController
{
private $answerRepository;
private $answer;
private $paginator;
/**
* AnswerController constructor
*
* @param \App\Repository\AnswerRepository $answerRepository Answer Repository
* @param \Knp\Component\Pager\PaginatorInterface $paginator
*/
public function __construct(AnswerRepository $answerRepository, PaginatorInterface $paginator)
{
$this->answerRepository = $answerRepository;
$this->paginator = $paginator;
}
/**
* Index action.
*
* @param \Symfony\Component\HttpFoundation\Request $request HTTP request
* @return \Symfony\Component\HttpFoundation\Response HTTP response
*
* @Route(
* "/",
* methods={"GET"},
* name="answer_index",
* )
*/
public function index(Request $request, PaginatorInterface $paginator, AnswerRepository $answerRepository): Response
{
$pagination = $paginator->paginate(
$answerRepository->queryAll(),
$request->query->getInt('page', 1),
AnswerRepository::PAGINATOR_ITEMS_PER_PAGE
);
return $this->render(
'answer/index.html.twig',
['pagination' => $pagination]
);
}
/**
* Create action.
*
* @param \Symfony\Component\HttpFoundation\Request $request HTTP request
*
* @param \App\Repository\AnswerRepository $answerRepository Answer repository
*
* @return \Symfony\Component\HttpFoundation\Response HTTP response
*
* @throws \Doctrine\ORM\ORMException
* @throws \Doctrine\ORM\OptimisticLockException
*
* @Route(
* "/create",
* methods={"GET", "POST"},
* name="answer_create",
* )
*/
public function create(Request $request, AnswerRepository $answerRepository): Response
{
$answer = new Answer();
$form = $this->createForm(AnswerType::class, $answer);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$answer->setQuestion($this->getQuestion());
$answerRepository->save($answer);
$this->addFlash('success', 'answer_created_successfully');
return $this->redirectToRoute('answer_index');
}
return $this->render(
'answer/create.html.twig',
['form' => $form->createView()]
);
}
}
答案表:
<?php
/**
* Answer type.
*/
namespace App\Form;
use App\Entity\Answer;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\EmailType;
use Symfony\Component\Form\Extension\Core\Type\HiddenType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
/**
* Class AnswerType.
*/
class AnswerType extends AbstractType
{
/**
* Builds the form.
*
* This method is called for each type in the hierarchy starting from the
* top most type. Type extensions can further modify the form.
*
* @see FormTypeExtensionInterface::buildForm()
*
* @param \Symfony\Component\Form\FormBuilderInterface $builder The form builder
* @param array $options The options
*/
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$builder->add(
'AnswerText',
TextType::class,
[
'label' => 'label_answertext',
'required' => true,
'attr' => ['max_length' => 200],
]
);
$builder->add(
'Nick',
TextType::class,
[
'label' => 'label_nick',
'required' => true,
'attr' => ['max_length' => 64],
]
);
$builder->add(
'Email',
EmailType::class,
[
'label' => 'label_email',
'required' => true,
'attr' => ['max_length' => 64],
]
);
$builder->add('is_best', HiddenType::class, [
'data' => '0',
]);
}
/**
* Configures the options for this type.
*
* @param \Symfony\Component\OptionsResolver\OptionsResolver $resolver The resolver for the options
*/
public function configureOptions(OptionsResolver $resolver): void
{
$resolver->setDefaults(['data_class' => Answer::class]);
}
/**
* Returns the prefix of the template block name for this type.
*
* The block prefix defaults to the underscored short class name with
* the "Type" suffix removed (e.g. "UserProfileType" => "user_profile").
*
* @return string The prefix of the template block name
*/
public function getBlockPrefix(): string
{
return 'answer';
}
}
和 AnswerEntity
<?php
namespace App\Entity;
use App\Repository\AnswerRepository;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity(repositoryClass=AnswerRepository::class)
* @ORM\Table(name="answers")
*/
class Answer
{
/**
* @ORM\Id
* @ORM\GeneratedValue
* @ORM\Column(type="integer")
*/
private $id;
/**
* @ORM\Column(type="string", length=200)
*/
private $answer_text;
/**
* @ORM\ManyToOne(targetEntity=Question::class, inversedBy="answer")
* @ORM\JoinColumn(nullable=false)
*/
private $question;
/**
* @ORM\Column(type="string", length=64)
*/
private $email;
/**
* @ORM\Column(type="string", length=64)
*/
private $Nick;
/**
* @ORM\Column(type="integer")
*/
private $isBest;
public function getId(): ?int
{
return $this->id;
}
public function getAnswerText(): ?string
{
return $this->answer_text;
}
public function setAnswerText(string $answer_text): void
{
$this->answer_text = $answer_text;
}
public function getQuestion(): ?Question
{
return $this->question;
}
public function setQuestion(?Question $question): void
{
$this->question = $question;
}
public function getEmail(): ?string
{
return $this->email;
}
public function setEmail(string $email): self
{
$this->email = $email;
return $this;
}
public function getNick(): ?string
{
return $this->Nick;
}
public function setNick(string $Nick): self
{
$this->Nick = $Nick;
return $this;
}
public function getIsBest(): ?int
{
return $this->isBest;
}
public function setIsBest(int $isBest): self
{
$this->isBest = $isBest;
return $this;
}
}
错误是: [在此处输入图片描述][1] [1]: https://i.stack.imgur.com/fYGpo.png
但我在 AnswerEntity 中有一个 getQuestion 函数,为什么它不读取它?它读取与实体相同的函数 setQuestion。
有没有机会换一种方式?
另外,我在到达 create_answer
的地方添加了部分问题模板代码 <a href="{{ url('answer_create', {id: questions.id}) }}" title="{{ 'create_answer'|trans }}">
{{ 'create_answer'|trans }}
</a>
答案在您发布的错误图像中,控制器中没有 $this->getQuestion()
,除非您创建该功能。
您可以使用 Doctrine 通过任何标识符获取问题实体
$question = this->getDoctrine()->getRepository(Question::class)->find($question_id);
然后你可以在你的$answer
对象中设置问题关系
$answer->setQuestion($question);
为什么你的路线中没有 questionId。我认为这是了解用户试图回答哪个问题的强制性数据。
在路由中使用请求参数 id
并在方法参数中键入 Question
ParamConverter
可以在您的控制器方法中注入正确的问题
/**
* ...
* @Route(
* "/create/{id}",
* methods={"GET", "POST"},
* name="answer_create",
* )
*/
public function create(Request $request, AnswerRepository $answerRepository, Question $question): Response
{
$answer = new Answer();
$answer->setQuestion($question);
// ....