路径模式不能多次引用变量

时间:2016-08-13 03:14:22

标签: symfony

设置:

  • Symfony 3
  • 为了保持简单,我将引用一个简单的AppBundle,其中Entity1Entity2为实体。
  • 每个实体没有特定参数,只有id
  • Entity2Entity1的子项,这意味着在SQL图表中,Entity2有一个外键entity1_id

要点:

我正在尝试建立以下路线:

  • /entity1/{id}/entity2/{id}/show

第一个{id}Entity1的ID,Entity2的第二个。

我的.yml文件:

entity1.yml

entity1_index:
    path: /
    defaults: { _controller: "AppBundle:Entity1:index" }
    methods: GET

entity1_show:
    path: /{id}/show
    defaults: { _controller: "AppBundle:Entity1:show" }
    methods: GET

entity1_new:
    path: /new
    defaults: { _controller: "AppBundle:Entity1:new" }
    methods: [GET, POST]

entity1_edit:
    path: /{id}/edit
    defaults: { _controller: "AppBundle:Entity1:edit" }
    methods: [GET, POST]

entity1_delete:
    path: /{id}/delete
    defaults: { _controller: "AppBundle:Entity1:delete" }
    methods: DELETE

# ENTITY2
entity2:
    resource: "@AppBundle/Resources/config/entity2.yml"
    prefix: /{id}/entity2

entity2.yml

 entity2_index:
    path: /
    defaults: { _controller: "AppBundle:Entity2:index" }
    methods: GET

entity2_show:
    path: /{id}/show
    defaults: { _controller: "AppBundle:Entity2:show" }
    methods: GET

entity2_new:
    path: /new
    defaults: { _controller: "AppBundle:Entity2:new" }
    methods: [GET, POST]

entity2_edit:
    path: /{id}/edit
    defaults: { _controller: "AppBundle:Entity2:edit" }
    methods: [GET, POST]

entity2_delete:
    path: /{id}/delete
    defaults: { _controller: "AppBundle:Entity2:delete" }
    methods: DELETE

问题:

路由模式不能多次引用变量,这就是我的问题。

我不知道该怎么做才能让Symfony区分每个{id}

3 个答案:

答案 0 :(得分:1)

我建议你使用Route annotations。我个人觉得使用它更容易。

例如,您可以执行以下操作:

/**
 * @Route("/editEntity1/{id1}/entity2/{id2}",
 *  defaults={"id1" = 0,"id2" = 0},
 *  name="editEntity1Route")
 */
public function editEntity1Action($id1, $id2, Request $request){
    ...
    // Now you can use both id variables like so:
    $eName1 = $id1->getName();
    $eName2 = $id2->getName();
    ...
}

我重命名了'editEntity1Route'路线,因为它明确地告诉你它是做什么的。在这种情况下编辑Enitity 1.然后在你的控制器中你将有“showEntity1”,“newEntity1”等其他路线......

在另一个控制器中,重定向到上述路线的简单方法如下:

...
$em = $this->getDoctrine()->getManager();
$qb = $em->createQueryBuilder();
$qb->select('e1')
    ->from('AppBundle:Entity1', 'e1')
    ->where('e1.e1_name = :e1_name')    // Example
    ->setParameter('e1_name', "sample name");
$entity1 = $qb->getQuery()->setMaxResults(1)->getOneOrNullResult();
...
$entity2 = $qb->getQuery()->setMaxResults(1)->getOneOrNullResult();

return $this->redirectToRoute('editEntity1Route', array(
        'id1' => $entity1->getId(),
        'id2' => $entity2->getId(),
));

此外,在Twig中,设置路径链接非常容易:

<a href="{{ path('editEntity1Route',
         {'id1':entity1.getId, 'id2':entity2.getId}) }}">Edit Entity1</a>

在上面的twig文件中,这假设你的控制器已传入变量'entity1'和'entity2'。

我认为如果您使用路由注释,这可能会为您提供有关如何实现此目的的一些想法。您仍然可以在Yaml文件中使用路由,我只是发现使用路由注释更明显。

答案 1 :(得分:0)

查看 entity1.yml

entity2:
resource: "@SalonBundle/Resources/config/dashboard/soushall.yml"
prefix: /{id}/soushall

尝试删除这些{id},因此路线变为/entity1/entity2/{id}/show

现在,您的{id}是来自Entity2的ID。由于Entity2具有链接到Entity2中的id的外键entity1_id,因此路由只需从Entity2读取一个id即可。

答案 2 :(得分:-1)

Hewwo〜

感谢Alvin的详细信息 我还没有尝试过注释路由,我还不熟悉它。
我将保留该帖子标记,截至目前,我已经制作了太多路由来切换到注释路由 但我会尝试下一个项目......;)

与此同时,我想出了如何解决我的问题 因此,这里有详细信息。

设置:与第一篇文章相同。

<强>解决方案:

重命名路线变量:

•entity1.yml

entity1_index:
    path: /
    defaults: { _controller: "AppBundle:Entity1:index" }
    methods: GET

entity1_show:
    path: /{idEntity1}/show
defaults: { _controller: "AppBundle:Entity1:show" }
methods: GET

entity1_new:
    path: /new
    defaults: { _controller: "AppBundle:Entity1:new" }
    methods: [GET, POST]

entity1_edit:
    path: /{idEntity1}/edit
    defaults: { _controller: "AppBundle:Entity1:edit" }
    methods: [GET, POST]

entity1_delete:
path: /{idEntity1}/delete
defaults: { _controller: "AppBundle:Entity1:delete" }
methods: DELETE

# ENTITY2
entity2:
    resource: "@AppBundle/Resources/config/entity2.yml"
    prefix: /{idEntity1}/entity2


•entity2.yml

entity2_index:
    path: /
    defaults: { _controller: "AppBundle:Entity2:index" }
    methods: GET

entity2_show:
    path: /{idEntity2}/show
    defaults: { _controller: "AppBundle:Entity2:show" }
    methods: GET

entity2_new:
    path: /new
    defaults: { _controller: "AppBundle:Entity2:new" }
    methods: [GET, POST]

entity2_edit:
    path: /{idEntity2}/edit
    defaults: { _controller: "AppBundle:Entity2:edit" }
    methods: [GET, POST]

entity2_delete:
    path: /{idEntity2}/delete
    defaults: { _controller: "AppBundle:Entity2:delete" }
    methods: DELETE


在实体中重命名$id

•Entity1.php

private $id;private $idEntity1;


*•Entity2.php

private $id;private $idEntity2;


编辑控制器:

[...]表示已跳过代码,因此未进行编辑。

•Entity1Controller.php

newAction更改:

return $this->redirectToRoute('entity1_show', array('id' => $entity1->getId()));

return $this->redirectToRoute('entity1_show', array('idEntity1' => $entity1->getId()));

对于我们找到的每个redirectToRoute,我们将重命名id变量以匹配我们的路线/实体变量。

editAction更改:

public function editAction(Request $request, Entity1 $entity1)
{
    [...]
    if ($editForm->isSubmitted() && $editForm->isValid()) {
        [...]
        return $this->redirectToRoute('entity1_edit', array('idEntity1' => $entity1->getId()));
    }
    [...]
}

•Entity2Controller.php:

在每个函数中,我们将父实体添加为变量。 如果没有完成,我们的路线将无效

indexAction更改:

public function indexAction()
{
    [...]
}

public function indexAction(Entity1 $entity1)
{
    [...]
    return $this->render('AppBundle:Default:index.html.twig', array(
        'entity1' => $entity1,
        'entity2s' => $entity2s,
    ));
}

newAction更改:

public function newAction(Request $request, Entity1 $entity1)
{
    [...]
    if ($form->isSubmitted() && $form->isValid()) {
        [...]
        return $this->redirectToRoute('entity2_show', array(
            'idEntity1'=>$entity1->getId(),
            'idEntity2'=>$entity2->getId()
        ));
    }
    return $this->render('AppBundle:Default:new.html.twig', array(
        'entity1' => $entity1,
        'entity2' => $entity2,
        'form' => $form->createView(),
    ));
}

showAction更改:

public function showAction(Entity1 $entity1, Entity2 $entity2)
{
    $deleteForm = $this->createDeleteForm($entity1, $entity2);
    return $this->render('AppBundle:Default:show.html.twig', array(
        'entity1' => $entity1,
        'entity2' => $entity2,
        'delete_form' => $deleteForm->createView(),
    ));
}

editAction的变化

public function editAction(Request $request, Entity1 $entity1, Entity2 $entity2)
{
    $deleteForm = $this->createDeleteForm($entity1, $entity2);
    [...]
    if ($editForm->isSubmitted() && $editForm->isValid()) {
        [...]
        return $this->redirectToRoute('entity2_edit', array(
            'idEntity1'=>$idEntity1,
            'idEntity2'=>$entity2->getId()
        ));
    }
    return $this->render('AppBundle:Default:edit.html.twig', array(
        'entity1' => $entity1,
        'entity2' => $entity2,
        'edit_form' => $editForm->createView(),
        'delete_form' => $deleteForm->createView(),
    ));
}

deleteAction更改:

public function deleteAction(Request $request, Entity1 $entity1, Entity2 $entity2)
{
    $form = $this->createDeleteForm($idEntity1, $entity2);
    [...]
    return $this->redirectToRoute('entity2_index', array('idEntity1' => $entity1->getId()));
}

createDeleteForm的变化

private function createDeleteForm(Entity1 $entity1, Entity2 $entity2)
{
    return $this->createFormBuilder()
        ->setAction($this->generateUrl('entity2_delete', array('idEntity1' => $entity1->getId(), 'idEntity2' => $entity2->getId())))
        ->setMethod('DELETE')
        ->getForm()
    ;
}


这总结了所需的所有变化...... 只要您可以通过整个项目替换代码,就可以快速完成......

感谢Alvin和大卫的回复 虽然我没有最终使用它们,但我相信它们将来会有用。
无论是对我还是对别人......:)

此主题现已解决...... ^^