Symfony: Как использовать одно и то же действие для CREATE и UPDATE?

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

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

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 ansfRoute`, с которым я работаю.

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

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


person Jake Wilson    schedule 04.08.2011    source источник


Ответы (3)


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

person P. R. Ribeiro    schedule 04.08.2011

Если возможно, я использую подход symfony crud:

Маршрутизация:

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

действия.класс.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(..).

person scube    schedule 04.08.2011

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

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

or

$this->gettroute()->matchesUrl()

person sjobe    schedule 04.08.2011