Symfony:如何对CREATE和UPDATE使用相同的操作?

时间:2011-08-04 19:40:37

标签: php symfony1 symfony-forms

假设我有一个网站,我在其中创建文章,我也编辑现有文章。用于创建新文章的模板页面与用于编辑现有文章的模板页面相同。唯一的区别是编辑表单已经添加了默认值/现有值。

我正试图弄清楚如何对两条路线使用相同的动作。这是我的路线:

article_new
  url: /article/new/
  class: sfDoctrineRoute
  options:
    model: MyArticle
    type: object
  param:
    module: article
    action: edit

article_edit
  url: /article/edit/:id/
  class: sfDoctrineRoute
  options:
    model: MyArticle
    type: object
  param:
    module: article
    action: edit
  requirements:
    id: /d+

因此,两篇文章都指出了以下行动:

public function executeEdit(sfWebRequest $request)
{
  $article = $this->getRoute()->getObject();

  $this->form = new MyForm( $article );

  // Binding and validation stuff here
  // .....
}

当您想要编辑文章时,这非常有用。 getRoute()->getObject()会自动从id slug中获取正确的文章,并将这些值作为默认值传递到表单中。完美。

但是使用article_new路线时,效果并不好。 getRoute()->getObject()返回数据库表中的第一篇文章,即使我没有为任何类型的id参数提供网址。因此,数据库中第一篇文章的信息将作为默认值传递到表单中。我显然不想要这个。

我还尝试删除class: sfDoctrineRoute路由中的article_new内容,然后删除我正在使用的getRoute()->getObject() fails because it's no longer an sfRoute`对象。

这里最好的方法是什么?为了节省编程时间和未来的维护时间,我想一举一动。

另外,我发现一个解决方案是,我可以查看$request->getParameter('id')是否为null,如果是,$article = array(),则使用{{1}检索文章}。这似乎工作正常,但我认为可能没有那么糟糕的解决方案。

3 个答案:

答案 0 :(得分:1)

解决方案是您自己指出的方向。这根本不是黑客攻击。我将_new作为正常路线并且仅作为对象路线_edit。像

article_new:
  url: /article/new/
  param:
    module: article
    action: edit

article_edit:
  url: /article/edit/:id/
  class: sfDoctrineRoute
  options:
    model: MyArticle
    type: object
  param:
    module: article
    action: edit
  requirements:
    id: /d+

在操作中,您只需要检查路线类型,例如

public function executeEdit(sfWebRequest $request)
{
  if($this->getRoute() instanceof sfRequestRoute){ // new action
    $article = new MyArticle();
  } else {
      $article = $this->getRoute()->getObject();
  }

  $this->form = new MyForm( $article );

  // Binding and validation stuff here
  // .....
}

测试$ request-> hasParameter('id')是否也是一种有效的方法。实际上,sfFormDoctrine也是这样做的,以确定表单是否处于编辑模式下插入模式。

答案 1 :(得分:1)

如果可能的话,我正在使用symfony crud方法:

路由:

article:
  class: sfDoctrineRouteCollection
  options:
    model:                article
    module:               article
    prefix_path:          /article
    column:               id
    with_wildcard_routes: true

的actions.class.php:

  public function executeEdit(sfWebRequest $request)
  {
    $this->forward404Unless($article = Doctrine_Core::getTable('Article')->find(array($request->getParameter('id'))), sprintf('Object Gutschein does not exist (%s).', $request->getParameter('id')));
    $this->form = new ArticleForm($gutschein);
  }

  public function executeUpdate(sfWebRequest $request)
  {
    $this->forward404Unless($request->isMethod(sfRequest::POST) || $request->isMethod(sfRequest::PUT));
    $this->forward404Unless($article = Doctrine_Core::getTable('Article')->find(array($request->getParameter('id'))), sprintf('Object Article does not exist (%s).', $request->getParameter('id')));
    $this->form = new ArticleForm($gutschein);

    $this->processForm($request, $this->form);

    $this->setTemplate('edit');
  }

  protected function processForm(sfWebRequest $request, sfForm $form)
  {
    $form->bind($request->getParameter($form->getName()), $request->getFiles($form->getName()));
    if ($form->isValid())
    {
      $gutschein = $form->save();

      $this->redirect('article/edit?id='.$gutschein->getId());
    }
  }

您可以在processForm(..)中执行所有表单处理。

答案 2 :(得分:0)

$request->getParameter('id')看起来根本不是hacky,但你也可以使用if语句和

  

$这 - > getRoute() - > matchesParameters()

  

$这 - > getroute() - > matchesUrl()