2011-12-30 50 views
7

条件我有类似如下的关系记录:Yii的关联记录与来自其他表

  • 也有网友(表用户)与IDS
  • 有类别(表类别)ID,名称
  • 没有与ID,身体篇(表项目),CATEGORY_ID
  • 再有就是用的article_id表read_articles邀请,USER_ID

因此用户可以看到一个类别中所有文章的列表。他们可以点击一篇文章,它会在read_articles表中添加一个条目(user_id,article_id)。

我希望能够使用Yii的ActiveRecord获取给定类别中尚未被当前用户读取并显示的所有文章。我一直在用SQL来思考它,但我不确定如何将它适用于我的ActiveRecord设置。我的第一个想法是在文章活跃记录上的参数化范围:

public function unread($userId) 
{ 
    $this->getDbCriteria()->mergeWith(array(
     'alias' => 'articles', 
     'condition' => 'not exists (SELECT * ' 
      . 'FROM user_read_articles ' 
      . 'WHERE articles.id=user_read_articles.article_id ' 
      . 'AND read_articles.user_id=' . (int)$userId 
      . ')', 
    )); 
} 

它似乎在工作,但它感觉真的很脏。

有没有更干净的方式来做我在ActiveRecord中谈论的?或者我应该考虑转向更简单的SQL并自己处理这样的事情(但是会失去很多AR的优点)?

编辑下面是上述车型的关系:(声明,这些将被截断,只相关部分)

UserActiveRecord

public function relations() 
{ 
    return array(
     'categories' => array(
      self::HAS_MANY, 
      'UserCategoryActiveRecord', 
      'user_id'), 
     // I added this early using gii, never really used it... 
     'readArticles' => array(
      self::HAS_MANY, 
      'UserReadArticleActiveRecord', 
      'user_id'), 
    ); 
} 

UserCategoryActiveRecord

public function relations() 
{ 
    return array(
     'user' => array(
      self::BELONGS_TO, 
      'UserActiveRecord', 
      'user_id'), 
     'articles' => array(
      self::HAS_MANY, 
      'ArticleActiveRecord', 
      'category_id', 
      'order' => 'articles.pub_date DESC'), 
    ); 
} 

ArticleActiveRecord

public function relations() 
{ 
    return array(
     'category' => array(
      self::BELONGS_TO, 
      'CategoryActiveRecord', 
      'category_id'), 
    ); 
} 

我也在创建这个时做了一个“UserReadArticleActiveRecord”,但我从来没有使用过这个模型,它几乎是空的。

在所有的诚实中,我一直在考虑转向Symfony2和Doctrine,只是放弃主动记录。我知道这并不能解决这个问题,但我可能会放弃这一点,并暂时保留当前的解决方案。

+0

你有关系定义从Articles到UserReadArticles?如果是这样,我敢肯定你可以在你命名的作用域的某个地方包含关系名称。 – lucifurious 2012-01-07 19:42:32

+0

我可以制作UserReadArticles,但我不确定我知道如何将它放入命名范围。 – Matt 2012-01-08 03:21:09

+0

告诉我定义的关系 – 2012-01-12 13:05:49

回答

4

为了得到阅读文章,你可以定义你的用户模型MANY_MANY关系如下所述:

http://www.yiiframework.com/doc/guide/1.1/en/database.arr

我不认为你需要代理模型UserReadArticles,你只需要适当地定义关系。

为了得到未读文章,我也遇到了问题思考Yii的方式做到这一点,但比使用子选择查询做留下了更有效的方式JOIN来user_read_articles,检查是否从user_read_articles IS NULL(没有匹配的行)是这样的:

$this->getDbCriteria()->mergeWith(array(
    'alias' => 'articles', 
    'join' => 'LEFT JOIN user_read_articles ON articles.id=user_read_articles.article_id', 
    'condition' => 'user_read_articles.article_id IS NULL', 
)); 
相关问题