[英]Symfony error (“Catchable Fatal Error: Object of class Proxies__CG__\AppBundle\Entity\Type could not be converted to string”)
I want the Game entity to appear with the related Type. 我希望游戏实体与相关的类型一起出现。 It's a many-to-one relation for the Game and a one-to-many for the Type entity.
对于游戏来说,这是多对一的关系,对于类型实体来说,是一对多的关系。 So a Game can have 1 Type while a Type can have many Games.
因此,一个游戏可以有1种类型,而一个类型可以有许多种游戏。
I get the error: 我收到错误:
An exception has been thrown during the rendering of a template ("Catchable Fatal Error: Object of class Proxies__CG__\\AppBundle\\Entity\\Type could not be converted to string").
呈现模板期间引发了异常(“可捕获的致命错误:Proxies__CG __ \\ AppBundle \\ Entity \\ Type类的对象无法转换为字符串”)。
When scrolling down it points to line 14 of the views/game/show.html.twig file: 向下滚动时,它指向views / game / show.html.twig文件的第14行:
<tr>
<th>Type</th>
<td>{{ game.type}}</td>
</tr>
The question: how do I show the current Game's Type in the view? 问题:如何在视图中显示当前游戏的类型?
Here's my code: 这是我的代码:
GameController.php: GameController.php:
<?php
namespace AppBundle\Controller;
use AppBundle\Entity\Game;
use AppBundle\Entity\Type;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Component\HttpFoundation\Request;
/**
* Game controller.
*
* @Route("game")
*/
class GameController extends Controller
{
/**
* Lists all game entities.
*
* @Route("/", name="game_index")
* @Method("GET")
*/
public function indexAction()
{
$em = $this->getDoctrine()->getManager();
$games = $em->getRepository('AppBundle:Game')->findAll();
return $this->render('game/index.html.twig', array(
'games' => $games,
));
}
/**
* Creates a new game entity.
*
* @Route("/new", name="game_new")
* @Method({"GET", "POST"})
*/
public function newAction(Request $request)
{
$game = new Game();
$form = $this->createForm('AppBundle\Form\GameType', $game);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($game);
$em->flush($game);
return $this->redirectToRoute('game_show', array('id' => $game->getId()));
}
return $this->render('game/new.html.twig', array(
'game' => $game,
'form' => $form->createView(),
));
}
/**
* Finds and displays a game entity.
*
* @Route("/{id}", name="game_show")
* @Method("GET")
* @inheritdoc
*
*/
public function showAction(Game $game, Type $type)
{
$deleteForm = $this->createDeleteForm($game);
return $this->render('game/show.html.twig', array(
'game' => $game,
'type' => $game->getType(),
'delete_form' => $deleteForm->createView(),
));
}
/**
* Displays a form to edit an existing game entity.
*
* @Route("/{id}/edit", name="game_edit")
* @Method({"GET", "POST"})
*/
public function editAction(Request $request, Game $game)
{
$deleteForm = $this->createDeleteForm($game);
$editForm = $this->createForm('AppBundle\Form\GameType', $game);
$editForm->handleRequest($request);
if ($editForm->isSubmitted() && $editForm->isValid()) {
$this->getDoctrine()->getManager()->flush();
return $this->redirectToRoute('game_show', array('id' => $game->getId()));
}
return $this->render('game/edit.html.twig', array(
'game' => $game,
'edit_form' => $editForm->createView(),
'delete_form' => $deleteForm->createView(),
));
}
/**
* Deletes a game entity.
*
* @Route("/{id}", name="game_delete")
* @Method("DELETE")
*/
public function deleteAction(Request $request, Game $game)
{
$form = $this->createDeleteForm($game);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->remove($game);
$em->flush($game);
}
return $this->redirectToRoute('game_index');
}
/**
* Creates a form to delete a game entity.
*
* @param Game $game The game entity
*
* @return \Symfony\Component\Form\Form The form
*/
private function createDeleteForm(Game $game)
{
return $this->createFormBuilder()
->setAction($this->generateUrl('game_delete', array('id' => $game->getId())))
->setMethod('DELETE')
->getForm()
;
}
}
TypeController.php TypeController.php
<?php
namespace AppBundle\Controller;
use AppBundle\Entity\Type;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;use Symfony\Component\HttpFoundation\Request;
/**
* Type controller.
*
* @Route("type")
*/
class TypeController extends Controller
{
/**
* Lists all type entities.
*
* @Route("/", name="type_index")
* @Method("GET")
*/
public function indexAction()
{
$em = $this->getDoctrine()->getManager();
$types = $em->getRepository('AppBundle:Type')->findAll();
return $this->render('type/index.html.twig', array(
'types' => $types,
));
}
/**
* Creates a new type entity.
*
* @Route("/new", name="type_new")
* @Method({"GET", "POST"})
*/
public function newAction(Request $request)
{
$type = new Type();
$form = $this->createForm('AppBundle\Form\TypeType', $type);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($type);
$em->flush($type);
return $this->redirectToRoute('type_show', array('id' => $type->getId()));
}
return $this->render('type/new.html.twig', array(
'type' => $type,
'form' => $form->createView(),
));
}
/**
* Finds and displays a type entity.
*
* @Route("/{id}", name="type_show")
* @Method("GET")
*/
public function showAction(Type $type)
{
$deleteForm = $this->createDeleteForm($type);
return $this->render('type/show.html.twig', array(
'type' => $type,
'delete_form' => $deleteForm->createView(),
));
}
/**
* Displays a form to edit an existing type entity.
*
* @Route("/{id}/edit", name="type_edit")
* @Method({"GET", "POST"})
*/
public function editAction(Request $request, Type $type)
{
$deleteForm = $this->createDeleteForm($type);
$editForm = $this->createForm('AppBundle\Form\TypeType', $type);
$editForm->handleRequest($request);
if ($editForm->isSubmitted() && $editForm->isValid()) {
$this->getDoctrine()->getManager()->flush();
return $this->redirectToRoute('type_edit', array('id' => $type->getId()));
}
return $this->render('type/edit.html.twig', array(
'type' => $type,
'edit_form' => $editForm->createView(),
'delete_form' => $deleteForm->createView(),
));
}
/**
* Deletes a type entity.
*
* @Route("/{id}", name="type_delete")
* @Method("DELETE")
*/
public function deleteAction(Request $request, Type $type)
{
$form = $this->createDeleteForm($type);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->remove($type);
$em->flush($type);
}
return $this->redirectToRoute('type_index');
}
/**
* Creates a form to delete a type entity.
*
* @param Type $type The type entity
*
* @return \Symfony\Component\Form\Form The form
*/
private function createDeleteForm(Type $type)
{
return $this->createFormBuilder()
->setAction($this->generateUrl('type_delete', array('id' => $type->getId())))
->setMethod('DELETE')
->getForm()
;
}
}
Game.php Game.php
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
use Symfony\Component\Validator\Constraints as Assert;
/**
* Game
*
* @ORM\Table(name="game")
* @ORM\Entity(repositoryClass="AppBundle\Repository\GameRepository")
*/
class Game
{
/**
* @ORM\ManyToOne(targetEntity="Type", inversedBy="games")
* @ORM\JoinColumn(name="type_id", referencedColumnName="id")
*/
private $type;
/**
* @var int
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @var string
* @Assert\NotBlank()
* @Assert\Length(
* min = "3",
* max = "100"
* )
* @ORM\Column(name="name", type="string", length=255, unique=true)
*/
private $name;
/**
* Get id
*
* @return int
*/
public function getId()
{
return $this->id;
}
/**
* Set name
*
* @param string $name
*
* @return Game
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* @return string
*/
public function getName()
{
return $this->name;
}
/**
* @return mixed
*/
public function getType()
{
return $this->type;
}
/**
* @param mixed $type
*/
public function setType($type)
{
$this->type = $type;
}
}
Type.php Type.php
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
/**
* Type
*
* @ORM\Table(name="type")
* @ORM\Entity(repositoryClass="AppBundle\Repository\TypeRepository")
*/
class Type
{
/**
* @ORM\OneToMany(targetEntity="Game", mappedBy="type")
*/
private $games;
public function __construct()
{
$this->games = new ArrayCollection();
}
/**
* @var int
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @var string
*
* @ORM\Column(name="name", type="string", length=255)
*/
private $name;
/**
* Get id
*
* @return int
*/
public function getId()
{
return $this->id;
}
/**
* Set name
*
* @param string $name
*
* @return Type
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* @return string
*/
public function getName()
{
return $this->name;
}
/**
* @return mixed
*/
public function getGames()
{
return $this->games;
}
/**
* @param mixed $games
*/
public function setGames($games)
{
$this->games = $games;
}
public function addGame(Game $game)
{
$this->games->add($game);
$game->setType($this);
}
public function removeGame(Game $game)
{
$this->games->removeElement($game);
}
}
GameType.php GameType.php
<?php
namespace AppBundle\Form;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class GameType extends AbstractType
{
/**
* {@inheritdoc}
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add( 'name', TextType::class, [
'attr' => [
'class' => 'form-control',
],
] );
$builder
->add( 'type', EntityType::class, [
'class' => 'AppBundle:Type',
'choice_label' => 'name',
'multiple' => false,
'expanded' => false,
'attr' => [
'class' => 'form-control',
],
] );
}
/**
* {@inheritdoc}
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'AppBundle\Entity\Game'
));
}
/**
* {@inheritdoc}
*/
public function getBlockPrefix()
{
return 'appbundle_game';
}
}
TypeType.php TypeType.php
<?php
namespace AppBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class TypeType extends AbstractType
{
/**
* {@inheritdoc}
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('name') ;
}
/**
* {@inheritdoc}
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'AppBundle\Entity\Type'
));
}
/**
* {@inheritdoc}
*/
public function getBlockPrefix()
{
return 'appbundle_type';
}
}
You need a bit of work in your GameType.php
form: 您需要以
GameType.php
形式进行一些工作:
// GameType.php
$builder
->add('type', EntityType::class, [
'class' => 'AppBundle:Type',
'placeholder' => ' ',
'choice_label' => function($type){
return $type->getName();
},
'multiple' => false, // a user can select only one option per submission
'expanded' => false // options will be presented in a <select> element; set this to true, to present the data as checkboxes
])
;
Then, in the game/show.html.twig
template: 然后,在
game/show.html.twig
模板中:
{{ game.type.name }} //supposing you want to display the name column of the types table
Tip: Each time you are facing this kind of trouble, you can use {{ dump(variable) }}
to check what's inside it. 提示:每次遇到此类麻烦时,都可以使用
{{ dump(variable) }}
来检查其中的内容。
For a full ManyToOne
example check this article. 对于一个完整的
ManyToOne
例如检查此文章。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.