无法猜测如何获得Doctrine实例

时间:2016-01-26 17:34:09

标签: php doctrine-orm doctrine symfony

我已经完成了将项目从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}}

4 个答案:

答案 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)

如果您有唯一字段,则应在实体定义中将它们标记为唯一:

the @column annotation中:

/**
 * @Column(type="string", length=32, unique=true, nullable=false)
 */
protected $name;

other unique constraints

/**
 * @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})。