【问题标题】:Yii Relational record with condition from other tableYii 与其他表条件的关系记录
【发布时间】:2011-12-30 18:27:43
【问题描述】:

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

  • 有ID的用户(表用户)
  • 有id、name的分类(表分类)
  • 有id、body、category_id的文章(表格文章)
  • 然后有一个表read_articles,article_id,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 的很多不错的功能)?

编辑以下是上述模型的关系:(免责声明,这些被截断为仅相关部分)

用户活动记录

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,并完全放弃主动记录。我知道它不能解决这个问题,但我可能会放弃它并暂时保留我当前的解决方案。

【问题讨论】:

  • 您是否定义了从文章到 UserReadArticles 的关系?如果是这样,我很确定您可以在命名范围内的某处包含关系名称。
  • 我可以制作 UserReadArticles,但我不确定我是否知道如何将其放入命名范围。
  • 显示定义的关系
  • 如果有帮助就添加它。顺便说一句,使用 Doctrine 2 会更容易解决这个问题,还是稍微不同?

标签: php activerecord yii


【解决方案1】:

要获得阅读文章,您可以在您的用户模型上定义 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',
) );

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-01
    相关资源
    最近更新 更多