alaboudi
alaboudi

Reputation: 3413

Creating Follower & Following relationships in Laravel 5

Im trying to create a function in laravel that will return all the user's followers through Laravel's dynamic property. It should look something like this:$user->followers.

I also have the following table structures:

--users--
id pk

--follows--
follower pk,fk
following pk,fk

I was trying to use the hasManyThrough function in the model but I haven seen an example in the documentation that lets me specify a custom primary key aside from an incremental id.

Upvotes: 0

Views: 2131

Answers (1)

macghriogair
macghriogair

Reputation: 1481

Citing from the docs:

If you would like to customize the keys of the relationship, you may pass them as the third and fourth arguments to thehasManyThrough method. The third argument is the name of the foreign key on the intermediate model, while the fourth argument is the name of the foreign key on the final model.

You should be able to pass your custom foreign key column names as described there.

--EDIT: After some reflection, I think hasManyThrough is not adequate for what you want to achieve (at least with the little information provided in the question). Instead belongsToMany should do:

In a fresh Laravel 5.2 installation, I created a migration for such pivot table (inspired by another post):

 public function up()
 {
     Schema::create('follows', function (Blueprint $table) {
         // Edit 2 without an incremental id
         // $table->increments('id');
         $table->integer('follower_id')->unsigned();
         $table->integer('followee_id')->unsigned();
         $table->foreign('follower_id')->references('id')
               ->on('users')
               ->onDelete('cascade');
         $table->foreign('followee_id')->references('id')
               ->on('users')
               ->onDelete('cascade');

         // Edit 2: with primary and unique constraint
         $table->primary(['follower_id', 'followee_id']);
         $table->unique(['follower_id', 'followee_id']);
     });
 }

And in App\User Model

public function followers()
{
    return $this->belongsToMany(
        self::class, 
        'follows',
        'followee_id',
        'follower_id'
    );
}
public function followees()
{
    return $this->belongsToMany(
        self::class,
        'follows',
        'follower_id',
        'followee_id'
    );
}

Then, after seeding some users and pivot relations, this works for me:

$user = User::first();
// user is followed by
echo json_encode($user->followers()->get());
// user is following
echo json_encode($user->followees()->get());

In a first version of this (trivial) example there were two primary keys: 'id' on 'users' and 'id' on 'follows', i.e. the defaults by convention. You can override your pk in your model like so protected $primaryKey = 'user_id';. There is a post on SO on this. Now the pivot table has a composite key which must be unique, which was the OPs intention I guess.

-- Edit 2: With the constraints in place you should add followers like so:

$user->followers()->sync([$anotherUser->id],false);

in order to avoid integrity constraint violation if the composite key should exist already. The sync method is suggested here.

Hope this helps.

Upvotes: 7

Related Questions