在 Symfony 前端应用程序中利用 Doctrine 关系

发布于 2024-09-26 03:35:34 字数 1374 浏览 3 评论 0 原文

让我们考虑以下简单的模式(在 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 应用程序。但在前端,您通常需要管理与登录用户相关的对象,因此您必须手动获取用户的 id,将 id 传递给模型并编写一堆方法来检索与该用户相关的对象,例如示例:

  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();
  }
}

这是微不足道的事情,但您必须为每个新关系手动编写此代码。我是否缺少某种利用教义关系的方法?无论如何,你会怎么做呢?谢谢。

Let's consider the following simple schema (in Doctrine, but Propel users are welcome too):

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

Now, if you create a route for Article model and generate a module via doctrine:generate-module-for-route frontend @article_route you get a CRUD application that manages all the articles. But in frontend you would normally want to manage objects related to signed-in User, so you have to manually get the id of the User, pass id to the model and write a bunch of methods that would retrieve objects related to this User, for example:

  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();  
    }
  }  

and model:

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();
  }
}

This is trivial stuff and yet you have to manually write this code for each new relation. Am I missing some kind of way to take advantage of Doctrine relations? Anyways, how would you do it? Thank you.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

电影里的梦 2024-10-03 03:35:34

我相信您应该能够使用自定义路由类来做到这一点。我从来没有这样做过,但是 More with Symfony 书中有一个教程: 高级路由。我的猜测是,它应该看起来像这样:

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。我还没有对此进行测试,但我认为这是解决问题的最佳方法。

I believe you should be able to do this with a custom routing class. I have never done this, but there is a tutorial in the More with Symfony book: Advanced Routing. My guess is that it should look something like this:

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;
  }
}

You would then need to set the routing class in routing.yml to use objectWithUserRoute. I haven't tested this, but I think it is the best way to go about solving the problem.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文