Использование преимуществ доктрины в веб-приложениях Symfony - PullRequest
0 голосов
/ 06 октября 2010

Давайте рассмотрим следующую простую схему (в Doctrine, но пользователи Propel тоже приветствуются):

User:
  columns:
    name: string
Article:
  columns:
    user_id: integer
    content: string
  relations:
    User:
      local: user_id
      foreign: id

Теперь, если вы создаете маршрут для модели Article и генерируете модуль с помощью doctrine:generate-module-for-route frontend @article_route, вы получаетеприложение CRUD, которое управляет всеми статьями.Но во внешнем интерфейсе вы обычно хотите управлять объектами, связанными с вошедшим в систему пользователем, поэтому вам нужно вручную получить идентификатор пользователя, передать идентификатор модели и написать набор методов, которые будут извлекать объекты, связанные с этим пользователем, дляпример:

  public function executeIndex(sfWebRequest $request)
  {
    $this->articles = Doctrine::getTable('Articles')
      ->getUserArticles(this->getUser());
  }
  public function executeShow(sfWebRequest $request)
  {
    $this->article = $this->getRoute()->getObject();

    if (!$this->article->belongsToUser($this->getUser()))
    {
      $this->redirect404();  
    }
  }  

и модель:

class ArticleTable extends Doctrine_Table
{
    public function getUserArticles(sfUser $user)
    {
      $q = $this->createQuery('a')
        ->where('a.user_id = ?', $user->getId());

      return $q->execute();
    }   
}

class Article extends BaseArticle
{
  public function belongsToUser(sfUser $user)
  {
    return $this->getUserId() == $user->getId();
  }
}

Это тривиальные вещи, и все же вы должны вручную написать этот код для каждого нового отношения.Я пропускаю какой-то способ использовать отношения Доктрины?В любом случае, как бы вы это сделали?Спасибо.

1 Ответ

0 голосов
/ 06 октября 2010

Полагаю, вы сможете сделать это с помощью пользовательского класса маршрутизации.Я никогда не делал этого, но в книге «Больше с Symfony» есть учебник: Advanced Routing .Я предполагаю, что это должно выглядеть примерно так:

class objectWithUserRoute extends sfDoctrineRoute
{
  public function matchesUrl($url, $context = array())
  {
    if (false === $parameters = parent::matchesUrl($url, $context))
    {
      return false;
    }

    $parameters['user_id'] = sfContext::getInstance()->getUser()->getId();

    return array_merge(array('user_id' => sfContext::getInstance()->getUser()->getId()), $parameters);
  }

  protected function getRealVariables()
  {
    return array_merge(array('user_id'), parent::getRealVariables());
  }

  protected function doConvertObjectToArray($object)
  {
    $parameters = parent::doConvertObjectToArray($object);

    unset($parameters['user_id']);

    return $parameters;
  }
}

Затем вам необходимо установить класс маршрутизации в routing.yml, чтобы использовать objectWithUserRoute.Я не проверял это, но думаю, что это лучший способ решить проблему.

...