2011-12-30 43 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', 
)); 
相關問題