Self-Linking a model or users follow users

Hello CakePHP community

I have an understanding question about linking models if my reasoning is correct at all.

As in most applications, I want to give users the opportunity to register. So I have a users table. Since I want to separate the user from the profile, I have a separate profiles table with a users-> hasOne (‘Profile’) association.

What I want to implement now is a “Follow” function like in Facebook, …, etc. Since here basically one user follows the other, a followers table / model doesn’t make sense to me. But if I’m right, according to CakePHP this is a many to many relationship. So I need a users, followers and followers_users table. However, since the followers table would only be a “copy” of the user table, this would be unnecessary redundant data.

So my question is on the one hand how I correctly create this in the database (tables) and on the other hand how I correctly set the relationships in the model (s).

Thanks in advance!

In your Users table (untested, but should be very close):

$this->belongsToMany('Following', [
	'className' => 'Users',
	'joinTable' => 'following_users',
	'foreignKey' => 'user_id', // the user doing the following
	'targetForeignKey' => 'following_id', // the user they are following
]);
1 Like

Thanks for the answer.

If I now want to apply the CounterCache behavior to the number of followers, is it correct that I have to create a followers_count field in the users table and have to change the relevant code as follows?

In the Users table:

$this->belongsToMany('Users', [
    'through' => 'FollowingUsers'
]);

And in the FollowingUsers table (to be created):

$this->addBehavior('CounterCache', [
    'Users' => ['followers_count']
 ]);

$this->belongsTo('Users', [
    'foreignKey' => 'user_id',
    'joinType' => 'INNER',
    'cascadeCallbacks' => true
]);
$this->belongsTo('Users', [
    'foreignKey' => 'following_user_id',
    'joinType' => 'INNER',
    'cascadeCallbacks' => true
]);

Never used the counter cache yet, so I can’t comment on this code. You do definitely have to add a column for the count. :slight_smile: