jarvan
jarvan

Reputation: 459

Gii doesn't recognize many-to-many relationship to itself?

enter image description here

So I am trying to implement a friendlist, the above is the SQL diagram I made for my simple project and after generating the Models. I realized there was something wrong with the way Gii generated the model.

I wanted to make a many-to-many relationship with User to itself, but this is what I got:

class User {
...

    public function getPosts()
    {
        return $this->hasMany(Post::className(), ['userId' => 'id']);
    }
}

class Friend {
...

    public function getFriend()
    {
        return $this->hasOne(Member::className(), ['id' => 'friendId']);
    }
}

The User class doesn't have any relationship with itself, I expected something like getUsers() inside of User, but it didn't generate it. I initially thought about not making a model with the junction table, but I did so just to see what would happen. I don't think I need it. So I am not sure how to do this correctly? Do I need to get rid of my Junction Table Models and Do I need to make the relationship between User to itself and User to Message manually? I thought about doing a many-to-many in User and Message and a many-to-many in User for User. Is this the right thing? Tell me if I am wrong. Thank you.

Upvotes: 0

Views: 257

Answers (1)

meysam
meysam

Reputation: 1794

You are on a true way. You need a junction table for implementing your goal. Easily as you done this, you must define two model: User and Friend. Now on your User model at first you must define a relation for get the list of all friends, Suppose call it getFriendsLists:

public function getFriendsLists()
{
    return $this->hasMany(Friend::className(), ['userId' => 'id']);
}

This relation says that "Get me all account that are connected with me, i.e. if my id is 102, this relation return all record of friend table that their userIds are 102". Well, now we get all friends with a relation on User model, let call him getFriends:

public function getFriends()
{
    return $this->hasMany(User::className(), ['friendId' => 'id']
                ->via('friendsList');
}

Notice that 'friendsList' as is a parameter of via method, is our predefined relation on top of this answer. Now easily you can get all account that are friends of our example (User with id 102):

public FriendController extends Controller
{
    // Some code goes here!
    public function actionFriendList($id)
    {
        $user = User::findOne($id);
        $friends = $user->friends;

        return $this->render('friend-list', ['friendsArray' => $friends]);
    }
}

And use them on your friend-list view file as $friendsArray variable. Extra note that $user->friends use friends relation that you defined on User model with getFriends method.

Upvotes: 2

Related Questions