"Невозможно угадать, как получить экземпляр Doctrine из информации запроса для параметра" person_id "при добавлении этого параметра в аргументы - PullRequest
0 голосов
/ 15 октября 2019

У меня ошибка от symfony 4 "Невозможно угадать, как получить экземпляр Doctrine из информации запроса для параметра" person_id ", уже опробованы варианты для связанных вопросов, которые я нашел в stackoverflow, но все они предлагают решить эту проблемус @paramconverter, но этот метод как-то связан с @route, я не думаю, что это то, что мне нужно.

Вот код в контроллере:

/**
 * @Route("/skill/new/", name="new_skill")
 * Method({"GET", "POST"})
 * @param Request $request
 * @param Person $person_id
 * @return \Symfony\Component\HttpFoundation\RedirectResponse|Response
 */
public function new(Request $request, Person $person_id) {
    $skill = new Skill();
    $form = $this->createFormBuilder($skill)
        ->add('name', TextType::class, array('attr' => array('class' => 'form-control')))
        ->add('level', TextareaType::class, array(
            'attr' => array('class' => 'form-control')
        ))
        ->add('save', SubmitType::class, array(
            'label' => 'Create',
            'attr' => array('class' => 'btn btn-primary mt-3')
        ))
        ->getForm();
    $form->handleRequest($request);
    if($form->isSubmitted() && $form->isValid()) {
        $skill = $form->getData();
        $entityManager = $this->getDoctrine()->getManager();
        $person = $entityManager->getRepository(Person::class)->find($person_id);
        $person->addSkill($skill);
        $entityManager->persist($skill);
        $entityManager->persist($person);
        $entityManager->flush();
        return $this->redirectToRoute('skill_list');
    }
    return $this->render('main/new.html.twig', array(
        'form' => $form->createView()
    ));
}

и от Personentity

class Person
{
/**
 * @ORM\Id()
 * @ORM\GeneratedValue()
 * @ORM\Column(type="integer")
 */
private $id;

/**
 * @ORM\Column(type="string", length=255)
 */
private $name;

/**
 * @ORM\OneToMany(targetEntity="App\Entity\Skill", mappedBy="person")
 */
private $skills;

public function __construct()
{
    $this->skills = new ArrayCollection();
}

public function getId(): ?int
{
    return $this->id;
}

public function getName(): ?string
{
    return $this->name;
}

public function setName(string $name): self
{
    $this->name = $name;

    return $this;
}

/**
 * @return Collection|Skill[]
 */
public function getSkills(): Collection
{
    return $this->skills;
}

public function addSkill(Skill $skill): self
{
    if (!$this->skills->contains($skill)) {
        $this->skills[] = $skill;
        $skill->setPerson($this);
    }

    return $this;
}

public function removeSkill(Skill $skill): self
{
    if ($this->skills->contains($skill)) {
        $this->skills->removeElement($skill);
        // set the owning side to null (unless already changed)
        if ($skill->getPerson() === $this) {
            $skill->setPerson(null);
        }
    }

    return $this;
}

}

С помощью @paramconverter я написал id param в маршруте, например "* @Route (" / skill / new / {id} ", name =" new_skill ", ноон выдает еще одну ошибку «Не найден маршрут для« GET / skill / new »

Я пытаюсь добиться того, чтобы при создании нового навыка он связывался с конкретным человеком с конкретным идентификатором, поэтому я сделал ассоциацию ManyToOneПоэтому, пока я нахожусь на маршруте "/ person / {{person.id}}", мне нужно добавить навык к этому конкретному идентификатору, а не всем.

Я думаю, что я допустил ошибку, написав person_id в аргументах функции, но в противном случае это можетне найти этот параметр в entitymanager. Как я могу решить это?

1 Ответ

1 голос
/ 15 октября 2019

Проблема в определении маршрута и подписи метода. Symfony не может определить, какой Person $person_id он должен получить. Если вы хотите, чтобы это был объект, вы должны назначить параметр URL для идентификатора, например,

@Route("/skill/new/{person_id}", name="new_skill")

. Это изменит URL-адрес с http://example.com/skill/new на http://example.com/skill/new/123, где 123 - это идентификатор, для которого вы хотите получить Person -объект. Теперь вы ДОЛЖНЫ иметь идентификатор человека в своем URL, иначе маршрут не будет совпадать (как вы уже заметили). Вы можете сделать это необязательным, изменив сигнатуру метода:

/**
 * @Route("/skill/new/{person_id}", name="new_skill")
 * Method({"GET", "POST"})
 * @param Request $request
 * @param Person $person_id
 * @return \Symfony\Component\HttpFoundation\RedirectResponse|Response
 */
public function new(Request $request, Person $person_id = null) {

Допуская значение null для $person_id, параметр url должен быть необязательным, поэтому вы сможете использовать http://example.com/skill/skill/new или http://example.com/skill/skill/new/123.

Если вы не хотите, чтобы сущность и вы только хотели, чтобы способ извлекать ее из URL-адреса без явного указания параметра маршрута, вы можете просто немного изменить код:

/**
 * @Route("/skill/new", name="new_skill")
 * Method({"GET", "POST"})
 * @param Request $request
 * @param Person $person_id
 * @return \Symfony\Component\HttpFoundation\RedirectResponse|Response
 */
public function new(Request $request) {
    $person_id = $request->query->get('person_id');
    ...

Если вы сейчас возьмете существующий URL и добавите параметр URL, он будет считан в вашем действии, например, http://example.com/skill/new?person_id=1234 установит $person_id в 1234. Если вы не укажете параметр, он будет нулевым.

Symfony также имеет команды отладки, которые помогают вам проверить, какие маршруты существуют и соответствуют ли они:

bin/console debug:router

bin/console router:match /skill/new
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...