Yii关系记录与其他表中的条件

Mat*_*att 7 php activerecord yii

我有一个类似于以下的关系记录:

  • 有用户(表用户)有id
  • 有类别(名称)的类别(表类别)
  • 有文章(表格文章)与id,body,category_id
  • 然后是一个带有article_id,user_id的表read_articles

因此,用户可以看到类别中所有文章的列表.他们可以点击文章,它会在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
            . ')',
    ) );
}
Run Code Online (Sandbox Code Playgroud)

它看起来很有效,但对我来说感觉很脏.

有没有更清洁的方法来做我在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' ),
    );
}
Run Code Online (Sandbox Code Playgroud)

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' ),
    );
}
Run Code Online (Sandbox Code Playgroud)

ArticleActiveRecord

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

我在构建它的过程中也提出了一个"UserReadArticleActiveRecord",但我从未使用过该模型,它几乎只是空的.

老实说,我一直在考虑转向Symfony2和Doctrine,只是放弃了积极的记录.我知道它并没有解决这个问题,但我可能会放弃这个并暂时保留我目前的解决方案.

Ste*_*veK 4

要获取已读文章,您可以在用户模型上定义 MANY_MANY 关系,如下所述:

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

我认为您不需要代理模型 UserReadArticles,您只需要正确定义关系即可。

为了获取未读的文章,我也很难考虑 Yii 的方法来做到这一点,但比使用子选择查询更有效的方法是对 user_read_articles 进行 LEFT JOIN 并检查 user_read_articles 中的列是否为 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',
) );
Run Code Online (Sandbox Code Playgroud)