How to make a conditional active record relationship in Yii


(Dfrey) #1

I have Post, Comment, and User in a Yii api. When a Post is queried, the result should be the Post data, the User that made the Post, and any Comments for that Post, and the User who made the Comment with complete User data.

The Comment table includes a created_by field which is the user_id in the User table.

To get a single Post, here is the controller:


public function actionView($id){

    $post = Post::find()

        ->innerJoinWith('user')

        ->joinWith('comments')

        ->where(['{{post}}.id' => $id])

        ->asArray()

        ->one();

    return $post;

}

This returns a single Post by id, and any Comments.

To get all posts:


public function actionIndex(){

   $posts = Post::find()

     ->joinWith('user', $eager)

     ->joinWith('comments', $eager)

     ->orderBy('updated_at DESC')

     ->limit(self::MAX_ROWS)

     ->asArray()

     ->all();

  return $posts;

}

In the Post model, the Comment relationship is set like this:


public function getComments()

{

    return $this

      ->hasMany(Comment::className(), ['object_id' => 'id']);

}

So this returns Comments if thre are any, but not the complete User data for each User who commented.

So I added this to getComments() in order to return the User data for the comments:


 ->joinWith('user u2','u2.id = comment.created_by')

Which does return the User data along with the Comment, EXCEPT… now actionIndex() only returns Posts that have Comments.

So I tried adding this which didn’t do anything:


->andOnCondition(['not', ['comment.created_by' => null]]

How do I conditionally include the joinWith only for Posts with Comments?


(Yiiframework) #2

Depending on what your user relation in the comment model is called (assuming "user"):




->with('comments.user')