【问题标题】:Symfony: How to use same action for CREATE and UPDATE?Symfony:如何对 CREATE 和 UPDATE 使用相同的操作?
【发布时间】:2011-08-04 19:40:36
【问题描述】:

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

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

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() 返回我的数据库表中的第一篇文章,即使我没有为 url 提供任何类型的 id 参数。因此,数据库中第一篇文章的信息作为默认值传递到表单中。我显然不想要这个。

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

这里最好的方法是什么?我想一次性完成所有操作,以节省编程时间和未来的维护时间。

我还发现一个解决方案是我可以检查$request->getParameter('id') 是否为null,如果是,则$article = array(),否则使用getRoute()->getObject() 检索文章。这似乎工作正常,但我认为可能会有更少的 hacky 解决方案。

【问题讨论】:

    标签: php symfony1 symfony-forms


    【解决方案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+
    

    在action中你只需要检查路由的类型,比如

    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 也是这样做的,以确定表单是否处于编辑模式或插入模式。

    【讨论】:

      【解决方案2】:

      如果可能的话,我正在使用 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(..) 中完成所有表单处理。

      【讨论】:

        【解决方案3】:

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

        $this->getRoute()->matchesParameters()

        $this->getroute()->matchesUrl()

        【讨论】:

          猜你喜欢
          • 2014-11-28
          • 1970-01-01
          • 2010-10-21
          • 1970-01-01
          • 2017-07-25
          • 2020-04-12
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多