无法在 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);
        // ....