Antonín Slejška
Antonín Slejška

Reputation: 2040

Yii2 Active Record: The best way to display related records

I have two tables: record, user and a junction table record_user. I display the records, which are related to the logged user, using the Active Record.

In the model User I have the following functions:

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

public function getRecords()
{
    return $this->hasMany(Record::className(), ['id' => 'record_id'])
        ->via('recordUsers');
}

See: http://www.yiiframework.com/doc-2.0/guide-db-active-record.html#junction-table

In the model RecordSearch I define the query for the Active Data Provider:

public function search($params)
{

// The Object with all records, to which has the user access (the id of the user is in the junction table record_user).
$loggedUserRecords = YiiUser::findOne(Yii::$app->user->identity->id)->records;

// From the object is extracted an array with ids.
$loggedUserRecordsIds = yii\helpers\ArrayHelper::getColumn($loggedUserRecords, 'id');

// The ids are used to filter the Record object.
$query = Record::find()->filterWhere(['id' => $loggedUserRecordsIds]);

$dataProvider = new ActiveDataProvider([
    'query' => $query,
]);
...

The code works as expected. But I would like to know, if there is a more direct way to display the related records, without the extraction of ids from the object.

Upvotes: 2

Views: 3485

Answers (2)

Antonín Slejška
Antonín Slejška

Reputation: 2040

As suggested by BHoft the fastest and most simple way is probably the following.

Model Record:

public function getRecordUsers()
{
    return $this->hasMany(RecordUser::className(), ['record_id' => 'id']);
}

Model RecordSearch:

$dataProvider = new ActiveDataProvider([
    'query' => Record::find()->joinWith(['recordUsers'])->where(['user_id'=> Yii::$app->user->identity->id]),
]);

Upvotes: 1

BHoft
BHoft

Reputation: 1663

I guess RecordSearch has this relations

public function getRecordUsers()
{
    return $this->hasMany(RecordUser::className(), ['record_id' => 'id']);
}

public function getUsers()
{
    return $this->hasMany(User::className(), ['id' => 'user_id'])
    ->via('recordUsers');
}

Or

public function getUsers()
{
    return $this->hasMany(User::className(), ['id' => 'user_id'])->viaTable('recordUsers', ['record_id' => 'id']);
}

then you should be able to check query something like:

$dataProvider = new ActiveDataProvider([
    'query' => Record::find()->joinWith(['users'])->where(['user_id'=> Yii::$app->user->identity->id]),
]);

if i didn't make a mistake.

Upvotes: 4

Related Questions