Symfony: Как использовать одно и то же действие для CREATE и UPDATE? - PullRequest
2 голосов
/ 04 августа 2011

Допустим, у меня есть веб-сайт, на котором я создаю статьи, а также редактирую существующие статьи. Страница шаблона для создания новых статей такая же, как страница шаблона для редактирования существующих статей. Единственное отличие состоит в том, что к форме для редактирования уже добавлены значения по умолчанию / существующие значения.

Я пытаюсь выяснить, как использовать одно и то же действие для обоих маршрутов. Вот мои маршруты:

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 и передает эти значения по умолчанию в форму. Совершенная.

Но с маршрутом article_new он работает не так хорошо. getRoute()->getObject() возвращает первую статью в моей таблице базы данных, хотя я не указывал в URL какой-либо параметр id. Таким образом, информация из первой статьи в базе данных передается в форму в качестве значений по умолчанию. Я, очевидно, не хочу этого.

Я также попытался удалить материал class: sfDoctrineRoute из маршрута article_new, но затем объект getRoute()->getObject() fails because it's no longer an sfRoute`, с которым я работаю.

Какой здесь лучший подход? Я хотел бы сделать все за одно действие, просто чтобы сэкономить время программирования и время на техническое обслуживание в будущем.

Также я обнаружил, что одним из решений является то, что я могу проверить, является ли $request->getParameter('id') null и, если да, то $article = array(), иначе статья извлекается с использованием getRoute()->getObject(). Кажется, это работает нормально, но я подумал, что может быть менее хакерское решение.

Ответы [ 3 ]

1 голос
/ 05 августа 2011

Если возможно, я использую подход 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 (..).

1 голос
/ 04 августа 2011

Решение в том направлении, которое вы указали сами. Это не хакерство вообще. Я бы оставил _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 делает то же самое, чтобы определить, находится ли форма в режиме редактирования или в режиме вставки.

0 голосов
/ 04 августа 2011

$request->getParameter('id') вовсе не кажется хакерским, но вы также можете использовать оператор if и

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

или

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

...