Symfony:如何对创建和更新使用相同的操作?

发布于 2024-11-27 18:10:37 字数 1446 浏览 1 评论 0原文

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

我正在尝试找出如何对两条路线使用相同的操作。这是我的路线:

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() 失败,因为它不再是sfRoute` 对象。

这里最好的方法是什么?我想一次完成所有事情,只是为了节省编程时间和将来的维护时间。

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

Lets say I have a website where I create articles and I also edit existing articles. The template page for creating new articles is the same as the template page for editing existing articles. The only difference is that the form for editing has default/existing values added to it already.

I'm trying to figure out how to use the same action for both routes. Here are my routes:

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+

So both articles point to the following action:

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

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

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

This works great when you want to edit an article. getRoute()->getObject() automatically get the correct article for you from the id slug and passes those values as defaults into the form. Perfect.

But with the article_new route, it doesn't work so well. The getRoute()->getObject() returns the first article in my database table, even though I didn't feed the url any type of id parameter. So the information from the first article in the database gets passed as default values into the form. I obviously don't want this.

I also tried removing the class: sfDoctrineRoute stuff from the article_new route but then getRoute()->getObject() fails because it's no longer ansfRoute` object that I'm working with.

What is the best approach here? I'd like to do everything in one action just to save programming time and future maintenance time.

Also I found that one solution is that I can check to see if $request->getParameter('id') is null and if so, then $article = array(), else the article is retrieved using the getRoute()->getObject(). That seems to work fine but I figured there might be less hacky solution.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

巷雨优美回忆 2024-12-04 18:10:37

解决方案就在你自己指出的方向上。这根本不是黑客行为。我将 _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 执行相同的操作以确定表单是否处于编辑模式或插入模式。

The solution is in the direction you pointed out yourself. It's not hacking at all. I'd leave the _new as normal route and as object route only _edit. Like

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+

In the action you only need to check the type of route, like

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
  // .....
}

Testing if $request->hasParameter('id') is also a valid approach. In fact, the sfFormDoctrine does the same in order to determine if the form is in a edit mode ou insert mode.

逐鹿 2024-12-04 18:10:37

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

If possible I'm using the symfony crud approach:

Routing:

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

You can do all your form handling in processForm(..).

浮世清欢 2024-12-04 18:10:37

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

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

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

$request->getParameter('id') doesnt seem hacky at all, but you could also use an if statement and

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

or

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文