Cannot autowire argument $tourist of "App\Controller\TouristController::edit()": it references class "App\Entity\Tourist" but no such service exists

148
14 марта 2022, 18:00

Изучаю Symfony 5. С помощью make:crud создал контроллер Tourist:

<?php
namespace App\Controller;
use App\Entity\Tourist;
use App\Form\TouristType;
use App\Repository\TouristRepository;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
/**
 * @Route("/tourist")
 */
class TouristController extends AbstractController
{
/**
 * @Route("/", name="tourist_index", methods={"GET"})
 */
public function index(TouristRepository $touristRepository): Response
{
    return $this->render('tourist/index.html.twig', [
        'tourists' => $touristRepository->findAll(),
    ]);
}
/**
 * @Route("/new", name="tourist_new", methods={"GET","POST"})
 */
public function new(Request $request): Response
{
    $tourist = new Tourist();
    $form = $this->createForm(TouristType::class, $tourist);
    $form->handleRequest($request);
    if ($form->isSubmitted() && $form->isValid()) {
        $entityManager = $this->getDoctrine()->getManager();
        $entityManager->persist($tourist);
        $entityManager->flush();
        return $this->redirectToRoute('tourist_index');
    }
    return $this->render('tourist/new.html.twig', [
        'tourist' => $tourist,
        'form' => $form->createView(),
    ]);
}
/**
 * @Route("/{id}", name="tourist_show", methods={"GET"})
 */
public function show(Tourist $tourist): Response
{
    return $this->render('tourist/show.html.twig', [
        'tourist' => $tourist,
    ]);
}
/**
 * @Route("/{id}/edit", name="tourist_edit", methods={"GET","POST"})
 */
public function edit(Request $request, Tourist $tourist): Response
{
    $form = $this->createForm(TouristType::class, $tourist);
    $form->handleRequest($request);
    if ($form->isSubmitted() && $form->isValid()) {
        $this->getDoctrine()->getManager()->flush();
        return $this->redirectToRoute('tourist_index');
    }
    return $this->render('tourist/edit.html.twig', [
        'tourist' => $tourist,
        'form' => $form->createView(),
    ]);
}
/**
 * @Route("/{id}", name="tourist_delete", methods={"DELETE"})
 */
public function delete(Request $request, Tourist $tourist): Response
{
    if ($this->isCsrfTokenValid('delete'.$tourist->getId(), $request->request->get('_token'))) {
        $entityManager = $this->getDoctrine()->getManager();
        $entityManager->remove($tourist);
        $entityManager->flush();
    }
    return $this->redirectToRoute('tourist_index');
}
}

Перейдя по ссылке /tourist/71/edit получаю ошибку:

Cannot autowire argument $tourist of "App\Controller\TouristController::edit()": it references class "App\Entity\Tourist" but no such service exists.

Я могу исправить эту ошибку, изменив метод edit:

public function edit($id, Request $request, TouristRepository         $touristRepository): Response
{
$tourist = $touristRepository->findOneBy(['id' => $id]);
$form = $this->createForm(TouristType::class, $tourist);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
    $this->getDoctrine()->getManager()->flush();
    return $this->redirectToRoute('tourist_index');
}
return $this->render('tourist/edit.html.twig', [
    'tourist' => $tourist,
    'form' => $form->createView(),
]);
}  

Вопрос: правильное ли это решение, и, если нет, то как правильно? И почему CRUD сгенерировался неправильно?
Спасибо.

Answer 1

Круд в общем и целом сгенерен верно.

Предполагается что в случае с edit методом (как собственно и с другими) отрабатывает ParamConverter который вам должен возвращать Tourist взятый по id, однако в силу того что с 3.4 версии Symfony Container инжектит в методы контроллера сервисы автоматически, очень вероятно что из за этого происходит странность. Вообще говоря в документации пишут о том что аннотацию @ParamConverter можно опускать при определенных условиях, но у вас по какой то причине происходит попытка внедрить Tourist как сервис.

Попробуйте использовать @ParamConverter явным способом, как , например, указано в документации. Ну и проверьте что он у вас не отключен (хотя в других методах ведь работает).

READ ALSO
PHP не возвращает заголовки

PHP не возвращает заголовки

Нашел код в интернете как послать заголовки и тогда продолжить выполнение скрипта

133
Ошибка верификации сертификата

Ошибка верификации сертификата

При запросе к некоторым сайтем через fopen() или через curl возникают ошибки типа

169
Разбиение скрипта на части

Разбиение скрипта на части

Есть скрипт, который парсит прайс в формате XMLОн написан так, что берёт в память объект XML и преобразует его в нужный вид, передавая данные...

147