vrt1515
vrt1515

Reputation: 163

Yii2 Getting data from 2 tables connected via junction table into gridview

I have 3 tables, play, user and user_play which is a junction table for the other ones (all of the models have been generated with gii and they have relationships and so on). I need to get data from play table based on the user(where user id = x) and send it to gridview.

I'd like to also display some data from user_play table, like the group attribute and count all the players signed up for the game:

 <?= GridView::widget([
    'dataProvider' => $dataProvider,
    'filterModel' => $searchModel,
    'columns' => [
        ['class' => 'yii\grid\SerialColumn'],
        'name',
        'date',
        'user_play.group',
        'user_play.userCount',
        'time',
        ['class' => 'yii\grid\ActionColumn'],
    ],
]); ?>

I have this relation in my user and play table:

 public function getUserPlays()
{
    return $this->hasMany(UserPlay::className(), ['user_id' => 'id']);
}

I also have similar relations in user and play table:

//user table
public function getPlay() 
{
    return $this->hasMany(Play::className(), ['id' => 'play_id'])
    ->via('userPlays');
}
//play table
public function getUser() 
{
    return $this->hasMany(User::className(), ['id' => 'user_id'])
    ->via('userPlays');
}

I don't know how to use the two above mentioned relations, could somebody explain this to me, or maybe post a link with some info please ? Can't find anything on the internets.

But this line of code gets me what I want, which is data from play table for a specific user:

   $plays = Play::find()
     ->joinWith(['userPlays'])
     ->where(['user_play.user_id' => Yii::$app->user->id])
     ->all();

But when I try to put this output into the data provider, I get an error: Call to a member function getCount() on a non-object

How can I send this data to the gridview dataprovider and display it ? Or maybe there is easier way to get the data that I want ? Please help.

Upvotes: 0

Views: 4063

Answers (2)

Beate
Beate

Reputation: 33

I know what was the problem, I had the same.

The trick is, to use ArrayDataProvider instead of ActiveDataProvider, then it works :)

    $dataProvider = new ArrayDataProvider([
    'allModels' => $model->userPlays,
    'sort' => [
        'attributes' => ['id', ...],
    ],
]);

should do it.

Upvotes: 2

Joe Miller
Joe Miller

Reputation: 3893

The structure you have set up looks right, so let's talk through it. You are starting from the User. Your User model has a many-to-many relationship with Plays, defined via the table user_plays. In your User model you have this; (I've renamed the function to make it clearer that you are getting multiple values)

 public function getUserPlays()
{
    return $this->hasMany(UserPlay::className(), ['user_id' => 'id']);
}
    public function getPlays() 
{
    return $this->hasMany(Play::className(), ['id' => 'play_id'])
    ->via('userPlays');
}

Any method that starts with the word 'get' allows to you use that method as if it were an attribute of the model e.g. $count = count($user->plays), foreach($user->plays as $play) etc etc. I'm not sure what you mean about the 'group' attribute, we'd need to see some code to know what you mean. If you need more complex functions to operate on our data then you need to define these as 'get' methods in your model. The Yii2 documentation explains in a bit more detail.

Upvotes: 0

Related Questions