Sultenhest
3 months ago

Self Referencing Many-To-Many Relationship

Posted 3 months ago by Sultenhest

Hello guys,

I'm currently building a pseudo-Twitter clone using TDD for Laravel practice and i'm stuck building the "follow" functionality.

As it is now, every user, has a profile (one-to-one, works fine), which is created on user registration. Profiles should now be able to follow, and be followed, by other profiles.

I've looked at the official Laravel documentation as well as this other post i found here Handling Self reference Many to Many relationships, but i can't seem to make it work. This is the code i've got:

Migration:

Schema::create('follows', function (Blueprint $table) {
    $table->primary(['follower_profile_id', 'followed_profile_id']);
        $table->unsignedBigInteger('follower_profile_id');
        $table->unsignedBigInteger('followed_profile_id');
        $table->timestamps();

        $table->foreign('follower_profile_id')->references('id')->on('profiles')->onDelete('cascade');
        $table->foreign('followed_profile_id')->references('id')->on('profiles')->onDelete('cascade');              
});

Route:

Route::post('/profile/{profile}/follow', '[email protected]');

ProfileController:

public function follow(Profile $profile)
{
    auth()->user()->profile()->following()->toggle($profile);

    return redirect($profile->path());
}

Profile model:

public function path()
{
    return "/profile/{$this->username}";
}

public function following()
{
    return $this->belongsToMany(Profile::class, 'follows', 'follower_profile_id', 'followed_profile_id');
}

public function followers()
{
    return $this->belongsToMany(Profile::class, 'follows', 'followed_profile_id', 'follower_profile_id');
}

Test file:

public function test_a_profile_can_follow_another_profile()
{
    $follower = factory('App\Profile')->create();

    $followed = factory('App\Profile')->create();

    $response = $this->actingAs($follower->user)
                    ->post($followed->path() . '/follow');

    $this->assertDatabaseHas('follows', [
        'follower_profile_id' => $follower->id,
        'followed_profile_id' => $followed->id
    ]);

    $response->assertRedirect($followed->path());
}

And this is what i get from running the test:

The table is empty.

Or if i remove the assertDatabaseHas part:

Response status code [500] is not a redirect status code.

What am i missing?

Please sign in or create an account to participate in this conversation.