无法猜测如何获取教义实例


Unable to guess how to get a Doctrine instance

我已经完成了将我的项目从Symfony 2.8更新到Symfony 3的过程,现在正在重新设计我的一个控制器,但遇到了一些麻烦。

我有一个子实体和控制器。 控制器具有基本路由

/**
* Child controller.
*
* @Route("/profile/{parentName}/{childName}")
*/

与操作

/**
 * 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(),
    );
}

但是,我不希望页面URL domain.com/parentname/childname/id 我希望它是 domain.com/parentname/childname

在 2.8 中,我的控制器是

/**
* 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(),
    );
}

它按照我想要的方式工作。

但是,如果在我更新的控制器中,我将 showAction 上的路由注释修改为

/**
* @Route("/", name="child_show")
* @Method("GET")
* @Template()
*/

我收到一个错误无法猜测如何从请求信息中获取 Doctrine 实例。我猜是因为需要 ID 来获取正确的 Child 实例? 但是,子实体中的子名称 ($name) 也是唯一的。

我有点被这个困住了。 谁能告诉我做错了什么? 我希望能够为儿童个人资料页面提供不包含 ID 但使用儿童姓名返回所需信息的路由。

更新以回应一些评论/问题 - 以下是我的子实体

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;
}
}

并将显示操作修改为

/**
* 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(),
    );
}

但是我现在收到错误AppBundle''实体''子对象未找到。

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 

找不到实体,因为教义找不到名字为 {name} 和父名 parentName 的孩子......这似乎是合法的,因为父名称在子实体中不存在。

两种解决方案:

1 - 从未尝试过,但可能会起作用:在 Child 中创建 getParentName() 并使其return $this->parent->getName()

2 - 在控制器操作的顶部添加参数转换器注释:

/**
 * 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"...(顺便说一下,这真的是你想要的吗?不要忘记在控制器中use ParamConverter。

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

@column注释中:

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

或者对于其他唯一约束:

/**
 * @entity
 * @Table(name="child", uniqueConstraints{   
 *     @UniqueConstraint(name="name_something_unique", columns = {"name", "something"})
 * })
 */

如果为name添加@column唯一约束,则findOneByName可能会按预期工作。

您现在也可以使其像这样工作:

$childs = $em->getRepository('AppBundle:Child')->findBy( array('name' => $childName ));

然后你得到一个Collection,如果你确定它是唯一的,你可以简单地得到第一个元素,如果集合不为空......

if( ! $childs->isEmpty() ){
    $first = $childs->first();
}

我收到相同的错误消息,但我想,情况与您的情况略有不同。

我需要在自己的树枝模板中呈现特定文章。所以我有:

<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]);
}

@Route的那{name}改变了一切。我的意思是导致错误。所以我需要确保我不应该像锚元素 ({ 'title': article.title|lower } 'title' 部分那样{title}而不是{name}

@Dan Costinel

我收到了相同的错误消息,但我想,方式与您的略有不同。

"无法为命名路由"users_delete"生成 URL,因为此类路由不存在"

我忘了在路由.yml的路由中添加请求的{变量}

users_delete:
    path:     /{id}/modifier
    defaults: { _controller: ReservationBundle:Users:modifier }

这就是为什么我的控制器无法访问 $request 变量中预期的信息的原因:

公共函数修饰符操作(请求$request,用户$user) {}

但那是你的安维尔让我走上了正确的轨道:

@Route中的那个{名称}改变了一切。我的意思是这导致了 错误。所以我需要确保我应该 在我的锚元素的"标题"部分中具有{标题}({"标题": 文章标题|下 })。