2010-10-06 5 views
0

Рассмотрим следующую простую схему (в Учении, но пользователи Propel тоже приветствуются):Воспользовавшись отношений Doctrine в веб-интерфейсе приложений в Symfony

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

Теперь, если вы создаете маршрут для статьи модели и генерировать модуль через 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(); 
    } 
} 

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

ответ

0

Я считаю, что вы должны сделать это с помощью настраиваемого класса маршрутизации. Я никогда этого не делал, но в книге More with 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. Я не тестировал это, но я думаю, что это лучший способ решить проблему.

+0

sfContext :: getInstance() -> getUser() возвращает null, вероятно, потому что пользователь получает экземпляр после маршрутизации. Должен ли я изменить порядок заводской загрузки? И как? – Dziamid

+0

Хм, так оно и есть - я не знаю, почему мой предыдущий тест удался. Похоже, вы не можете использовать эту технику ':-(' – lonesomeday