Yii2 查询 space 中的帖子

Yii2 query for posts in a space

我有一个带有 post table、内容 table 和 space table.

的数据库

一个post是一种内容,一个space是很多post的容器。我想在 space 中获取所有 post。

Post:

id   object_id
--------------
1    22

内容(object_id --> post.id):

id   space_id
------------------------
22   3

Space (id --> content.space_id):

id   
--------------
3

要在 space 内获得 posts,控制器函数如下所示:

$posts = Post::find()
  ->joinWith('content', false)
  ->where(['{{content}}.space_id' => $space_id])
  ->all();

并且 Post 模型具有此函数来获取 post:

的内容对象
public function getContent() {
   return $this->hasOne(Content::className(), ['object_id' => 'id'])->andOnCondition(['{{content}}.object_model' => 'humhub\modules\post\models\Post']);
}

在数据库架构发生变化之前,这一直运行良好。

现在内容 table 中不再有 space_id 列。相反,有一个新的 table contentcontainer,其中 pk 字段取代了 space_id,还有一个 class 字段(即 space class) 来识别PK是针对space(table中还有一个class)。

tables/relationships 现在是:

Post Table:

id   object_id
--------------
1    22

内容table(object_id --> post.id):

id   contentcontainer_id
------------------------
22   5

内容容器Table (id --> content.contentcontainer_id)

id   pk   class
---------------
5    3    //Space

Space (id --> contentcontainer):

id   
--------------
3

要在 space 中获取所有 posts,我现在必须 link 3 tables: post,content,contentcontainer.

我是否将 contentcontainer 关系添加到 Post 模型?或者修改Post模型中的内容模型关系?不确定如何在不编写大草率查询的情况下最好地解决问题。

我将控制器功能更改为:

$posts = Post::find()
  ->where(['{{contentcontainer}}.pk' => $space_id])
  ->andWhere(['{{contentcontainer}}.class' => 'humhub\modules\space\models\Space'])

不确定这是否正确,我无法在 Post 模型中设置 contentcontainer 关系。

您似乎有一个 交汇点 table - contentcontainer。 Yii2 官方文档中有一个示例 how to decalre relation via a junction table.

在您的案例中,Post 模型中的关系可能是这样的:

public function getItems()
{
    return $this->hasMany(Content::className(), ['id' => 'pk'])
        ->viaTable('contentcontainer', ['class' => 'space_id']);
}

现在您的控制器函数将 $posts 执行两个连接而不是一个连接。

Space 模型中创建此方法:

public function getPosts() {
  return Post::find()
    ->innerJoin('contentcontainer', ['and', 
        'contentcontainer.pk = space.id',
        'contentcontainer.class = "humhub\modules\space\models\Space"'])
    ->innerJoin('content', 'content.contentcontainer_id = contentcontainer.id')
    ->innerJoin('post', 'post.object_id = content.id');
}

这是我解决这个问题的方法(结果来自内容模型,而不是 Post 模型):

    $content = Content::find()
     ->joinWith('contentContainer')
     ->andWhere(['{{contentcontainer}}.pk' => $space_id])
     ->andWhere(['{{contentcontainer}}.class' => 'humhub\modules\space\models\Space'])
     ->andWhere(['{{content}}.object_model' => 'humhub\modules\post\models\Post'])
     ->asArray()
     ->all();