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 slug и предава тези стойности като стойности по подразбиране във формуляра. перфектен

Но с маршрута 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

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(..).

person scube    schedule 04.08.2011

$request->getParameter('id') изобщо не изглежда хакерско, но можете също да използвате оператор if и

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

or

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

person sjobe    schedule 04.08.2011