我已经完成了将项目从Symfony 2.8更新到Symfony 3的过程,现在正在重新设计我的一个控制器但是遇到了一些麻烦。
我有一个Child实体和控制器。控制器有一个基本路径
/**
* Finds and displays a Child entity.
*
* @Route("/{id}", name="child_show")
* @Method("GET")
* @Template()
*/
public function showAction(Child $child)
{
$deleteForm = $this->createDeleteForm($child);
return array(
'child' => $child,
'delete_form' => $deleteForm->createView(),
);
}
带有动作
/**
* Child controller.
*
* @Route("/profile/{parentName}/{childName}")
*/
/**
* Finds and displays a Child entity.
*
* @Route("/", name="child_show")
* @Method("GET")
* @Template()
*/
public function showAction($childName)
{
$em = $this->getDoctrine()->getManager();
$entity = $em->getRepository('AppBundle:Child')->findOneByName($childName);
if (!$entity) {
throw $this->createNotFoundException('Unable to find Child entity.');
}
$deleteForm = $this->createDeleteForm($childName);
return array(
'entity' => $entity,
'delete_form' => $deleteForm->createView(),
);
}
但我不希望网页网址为domain.com/parentname/childname/id我希望它是domain.com/parentname/childname
2.8我的控制器是
/**
* @Route("/", name="child_show")
* @Method("GET")
* @Template()
*/
它按我的意愿工作。
但是,如果在我更新的控制器中,我将showAction上的路径注释修改为
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use AppBundle\Entity\User;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
/**
* Child
*
* @ORM\Table()
* @ORM\Entity(repositoryClass="AppBundle\Entity\ChildRepository")
* @UniqueEntity("name")
*/
class Child
{
/**
* @var integer
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @var string
*
* @ORM\Column(name="name", type="string", length=255, unique=true)
*/
private $name;
/*
* Todo - figure out how to use a date type for dateofbirth below and as well in users.yml fixtures file
*/
/**
* @var \DateTime
*
* @ORM\Column(name="date_of_birth", type="datetime")
*/
private $dateOfBirth;
//todo find ot why the parent variable here and Id variable in AppBundle:User are not mapped correctly
/**
* @ORM\ManyToOne(targetEntity="AppBundle\Entity\User", inversedBy="id")
* @ORM\JoinColumn(onDelete="CASCADE")
*/
private $parent;
/**
* @return User
*/
public function getParent()
{
return $this->parent;
}
/**
* @param User $parent
*/
public function setParent(User $parent)
{
$this->parent = $parent;
}
/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set name
*
* @param string $name
*
* @return Child
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* @return string
*/
public function getName()
{
return $this->name;
}
/**
* Set dateOfBirth
*
* @param \DateTime $dateOfBirth
*
* @return Child
*/
public function setDateOfBirth($dateOfBirth)
{
$this->dateOfBirth = $dateOfBirth;
return $this;
}
/**
* Get dateOfBirth
*
* @return \DateTime
*/
public function getDateOfBirth()
{
return $this->dateOfBirth;
}
}
我收到错误无法猜测如何从请求信息中获取Doctrine实例。我想因为获取正确的Child实例需要Id?但是,Child实体中的childName($ name)也是唯一的。
我对此有点困惑。谁能告诉我我做错了什么?我希望能够为子配置文件页面设置一条路线,该路线不包含该ID,但使用该子项的名称来返回所需的信息。
更新以回应一些意见/问题 - 以下是我的儿童实体
/**
* Child controller.
*
* @Route("/profile/{parentName}/{name}")
*/
/**
* Finds and displays a Child entity.
*
* @Route("/", name="child_show")
* @Method("GET")
* @Template()
*/
public function showAction(Child $name)
{
$deleteForm = $this->createDeleteForm($name);
return array(
'child' => $name,
'delete_form' => $deleteForm->createView(),
);
}
并将showAction修改为
ERROR - Uncaught PHP Exception
Symfony\Component\HttpKernel\Exception\NotFoundHttpException: "AppBundle\Entity\Child object not found." at /Library/WebServer/Documents/story-project/app/cache/dev/classes.php line 7183
但我现在收到错误 AppBundle \ Entity \ Child对象未找到。
{{1}}
答案 0 :(得分:1)
找不到实体,因为Doctrine无法找到名称为{name}
且parentName为parentName
的Child ...这似乎是合法的,因为在Child实体中不存在parentName。
两种解决方案:
1 - 从未尝试过,但可能有效:在Child中创建getParentName()并使其成为return $this->parent->getName()
2 - 在Controller Action顶部添加ParamConverter注释:
/**
* Finds and displays a Child entity.
*
* @Route("/", name="child_show")
* @Method("GET")
* @Template()
* @ParamConverter("child", class="AppBundle:Child", options={"name" = "name"})
*/
public function showAction(Child $child)
这样,转换器只会考虑参数" name"在尝试检索您的Child实体时...(顺便说一句,这真的是您想要的吗?)
不要忘记控制器中的use
ParamConverter。
答案 1 :(得分:0)
如果您有唯一字段,则应在实体定义中将它们标记为唯一:
/**
* @Column(type="string", length=32, unique=true, nullable=false)
*/
protected $name;
/**
* @entity
* @Table(name="child", uniqueConstraints{
* @UniqueConstraint(name="name_something_unique", columns = {"name", "something"})
* })
*/
如果您为@column
添加name
唯一约束,那么您的findOneByName
可能会按预期工作。
你现在也可以这样工作:
$childs = $em->getRepository('AppBundle:Child')->findBy( array('name' => $childName ));
然后你得到一个Collection
,如果你确定它是唯一的,那么如果集合不是first,你可以简单地得到empty元素......
if( ! $childs->isEmpty() ){
$first = $childs->first();
}
答案 2 :(得分:0)
我收到了相同的错误消息,但我想,情况与你的情况有所不同。
我需要在自己的树枝模板中呈现特定文章。所以我有:
<a href="{{ path('article_show', { 'title': article.title|lower }) }}" class="pull-right">Read More</a>
,其中'title'
是表格中列的名称。
但在我的控制器课程中,我有:
/**
* @Route("/article/{name}", name="article_show")
* @Method("GET")
*/
public function showAction(Article $article)
{
return $this->render('AppBundle:Article:show.html.twig', ['article'=>$article]);
}
{name}
中的@Route
改变了一切。我的意思是导致错误。因此,我需要确保{name}
而不是{title}
,而不是我的锚元素'title'
中的{ 'title': article.title|lower }
部分{{1}}。
答案 3 :(得分:0)
@Dan Costinel
我收到了相同的错误消息,但我想,与你的有点不同。
“无法为指定路由生成URL”users_delete“,因为此类路由不存在”
我忘记在routing.yml中添加请求的{variable}
users_delete:
path: /{id}/modifier
defaults: { _controller: ReservationBundle:Users:modifier }
这就是为什么我的控制器无法访问$ request变量中预期的信息:
public function modifierAction(Request $ request,Users $ user) {}
但那是你的正确方法:
@Route中的{name}改变了一切。我的意思是这是造成的 错误。所以我需要确保而不是{name}我应该 我的锚元素的'title'部分有{title}({'title': article.title | lower})。