2017-04-05 11 views
0

投稿テーブル、コンテンツテーブル、およびスペーステーブルを持つDBがありました。スペース内の投稿のYii2クエリ

投稿はコンテンツの種類であり、スペースは多くの投稿のコンテナです。私はスペース内のすべての投稿を取得したい。

ポスト:

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

コンテンツ(OBJECT_ID - > post.id):

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

スペース(ID - > content.space_id):

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

へスペース内に投稿を取得すると、コントローラの機能は次のようになります。

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

そしてPostモデルはポストのためのコンテンツオブジェクトを取得するには、この機能を持っていた:データベーススキーマが変更されるまで

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

これは完全に働きました。

コンテンツテーブルには、もはやspace_idという列はありません。代わりに、space_idに置き換えられるpkフィールドとclassフィールド(つまりspaceクラス)を持つ新しいテーブルcontentcontainerがあり、PKがスペースであることを識別します(テーブルにはclassもあります)。

テーブル/関係は今、次のとおりです。

ポスト表:

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

コンテンツテーブル(OBJECT_ID - > post.id):

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

Contentcontainer表(ID - > content.contentcontainer_id)

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

スペース(ID - > contentcontainer):ポスト、コンテンツ、contentcontainer:

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

スペース内のすべての記事を取得するには、私は今、3つのテーブルをリンクする必要があります。

ポストモデルにcontentcontainer関係を追加しますか?または、ポストモデルでコンテンツモデルの関係を変更しますか?大したお粗末な質問を書かずにどのように取り組むのがベストか。

私はこれにコントローラ機能を変更:

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

ない、これは権利であると私はPostモデルでcontentcontainer関係を設定立ち往生していてください。

+0

、投稿してください3つのテーブルの構造 – gmc

+0

@gmcテーブル構造が追加されました – lilbiscuit

答えて

0

は、「私は(結果はモデルを投稿しない、コンテンツモデルから引っ張られる)、これを解決する方法は次のとおりです。

$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(); 
0

接合テーブル - contentcontainerのようです。公式のYii2文書how to decalre relation via a junction tableに例があります。

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

は今、あなたは、コントローラの機能が $posts一つのINSEADジョイン2をやって取得します: Postモデルであなたのケースの関係で

は次のようなものである可能性があります。

0

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'); 
} 
関連する問題