Relations Not Returning Expected Result

I am trying to create a Buddy List for users. I have a table named "buddies" and have an AR model as follows:




<?php

namespace app\models;

use Yii;


/**

 * This is the model class for table "buddies".

 *

 * @property string $id

 * @property string $user

 * @property string $buddy

 * @property integer $active

 */

class Buddies extends \yii\db\ActiveRecord

{

    /**

     * @inheritdoc

     */

    public static function tableName()

    {

        return 'buddies';

    }


    /**

     * @inheritdoc

     */

    public function rules()

    {

        return [

            [['active'], 'integer'],

            [['user', 'buddy'], 'string', 'max' => 45]

        ];

    }


    /**

     * @inheritdoc

     */

    public function attributeLabels()

    {

        return [

            'id' => Yii::t('app', 'ID'),

            'user' => Yii::t('app', 'User'),

            'buddy' => Yii::t('app', 'Buddy'),

            'active' => Yii::t('app', 'Active'),

        ];

    }

    


}



I have added fName and lName fields and the following relation to my User model:




    ...

    use app\models\Buddies;

    ...


    public function getBuddies()

    {

        return $this->hasMany(Buddies::className(), ['user' => 'username'])

        ->onCondition(['active'=>1]);       

    }



I want a list of buddies for the currently logged in user. Instead, I am returned a list of ALL users. Here is my query:




<?php                    

     $buddies = User::find()

                        ->joinWith('buddies')                                

                        ->asArray()

                        ->all();


      foreach($buddies as $bud){

 

                        echo "<div>".$bud['fName']." ".$bud['lName']."</div>";                                

      }

?>



Am I missing something? Please help.

For the currently logged in user you need to get him first and then call the buddy relation.

something like this:




$user = Yii::$app->user->identity;

$buddies = $user->buddies;



Thanks CeBe for the reply. But I am confused here.

Okay, so I need to set the current user to match Yii::$app->user->identity. To me, it would seem that I need to somehow assign the username property of the User class to hold the value of $user… but I am a bit confused.

In your example, you create a $user variable to hold the current user, then you define $buddies as $user->buddies. Where/how does this assign the username to the current $user?

I’m not sure how to assign the current $user so that the User::find() query can return the desired results.

Would I need to somehow pass this into the relation method?

When you have implemented authentication correctly Yii::$app->user->identity refers to the active record instance of the currently logged in user.

You may also get the user by User::find() if it is different in your application.

Okay. Echoing Yii::$app->user->identity does return my current user and authentication works fine. The problem I have is that the relation is returning all users, not only my "buddies". It seems as if the username parameter in my getBuddies method is not properly related.




return $this->hasMany(Buddies::className(), ['user' => 'username'])->onCondition(['active'=>1]);



In this code, I expect ‘user’ to be from my buddies table and ‘username’ from my user table. So that one username (current user) can return only the buddies where that username matches the ‘user’ field in the buddies table. Instead, what I have are all my users from my ‘user’ table showing up. I do, however, get all the properties I need but just not the right dataset.

You suggested setting the $user to Yii::$app->user->identity, so I created a new User object like this…




$u = new User;

$user = Yii::$app->user->identity;

$u->username = $user;                                  

$buddies = $user->buddies;



This appears to give me the desired users from the buddy table, however, I cannot access their matching properties in the user table such as fName and lName for these buddies. I do not want to subquery each username in a loop to get the fName and lName fields. There must be a better way than querying the database for each and every user iteration, which could be hundred of times per user. All I’m looking for is query that returns buddies.user and their corresponding user.fName and user.lName for the current user.username