Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Laravel Follow Laravel Package

hypefactors/laravel-follow

A Laravel package that adds follow and unfollow behavior to Eloquent models. Let users follow other users or any model, retrieve followers and following lists, check relationships, and count followers through a simple, polymorphic API.

View on GitHub
Deep Wiki
Context7

Getting Started

Install the package with Composer and run its migrations:

composer require hypefactors/laravel-follow
php artisan vendor:publish   # publish the package migration(s)
php artisan migrate

This creates the polymorphic follows table used to store follower/followable pairs. Check the published migration for the exact column names and indexes before building queries against it.

Next, add the package traits to the models that participate in the follow graph. The actor model gets CanFollow; models that can be followed get CanBeFollowed:

use Hypefactors\LaravelFollow\Traits\CanFollow;

class User extends Authenticatable
{
    use CanFollow;
}
use Hypefactors\LaravelFollow\Traits\CanBeFollowed;

class Post extends Model
{
    use CanBeFollowed;
}

The first day-to-day use case is a simple follow button: a user follows a post (or another user, topic, etc.), the app checks isFollowing(), and lists results through followings/followers:

$user->follow($post);
$user->unfollow($post);
$user->toggleFollow($post);

$user->isFollowing($post);   // bool
$post->isFollowedBy($user);  // bool

$user->followings; // models the user follows
$post->followers;  // models following the post

Because the relation is polymorphic, any Eloquent model can follow or be followed without schema changes.

Implementation Patterns

Controller endpoints for UI actions. Keep follow/unfollow tiny and idempotent. Use toggleFollow for a single-button UI and authorize first:

public function toggle(Post $post, Request $request)
{
    $this->authorize('follow', $post);

    $request->user()->toggleFollow($post);

    return back();
}

Check state before rendering. In Blade or an API resource, expose whether the current user follows the model so the front end can render the right button state:

'is_following' => $request->user()?->isFollowing($this->resource) ?? false,

Eager-load counts instead of counting collections. For listing pages, use withCount so you do not trigger N+1 queries:

$posts = Post::withCount('followers')->paginate();

foreach ($posts as $post) {
    echo $post->followers_count;
}

Build feeds from the follow graph. For a "following feed", collect the IDs of followed users/topics and query posts in a second step. Use the package's Follow model or the relationship query rather than loading full collections:

use Hypefactors\LaravelFollow\Models\Follow;

$followedUserIds = Follow::query()
    ->where('follower_type', $user->getMorphClass())
    ->where('follower_id', $user->id)
    ->where('followable_type', (new User)->getMorphClass())
    ->pluck('followable_id');

$feed = Post::whereIn('user_id', $followedUserIds)
    ->latest()
    ->paginate();

Paginate through the relationship, not the property. $post->followers loads the entire collection. For follower lists use $post->followers()->paginate() (or the equivalent relation query) so large accounts stay responsive.

Use it for more than user-follows. The same traits support following tags, teams, repositories, or any model. This is usually cleaner than adding several bespoke pivot tables.

Test the stored pivot rows. Assert against the follows table using getMorphClass() so tests keep working if you later adopt a morph map:

$user->follow($post);

$this->assertTrue($user->isFollowing($post));
$this->assertDatabaseHas('follows', [
    'follower_id'     => $user->id,
    'follower_type'   => $user->getMorphClass(),
    'followable_id'   => $post->id,
    'followable_type' => $post->getMorphClass(),
]);

Keep notification/side effects in your own layer. The package is a persistence helper; if you need "X followed you" notifications or activity records, dispatch your own events from the controller/service after a successful follow.

Gotchas and Tips

  • Morph map discipline. If you call Relation::enforceMorphMap(), register every followable and follower model. The follows table stores morph types, so changing a class name or aliasing later will orphan existing rows.
  • Mixed followings collections. $user->followings is polymorphic and may contain users, posts, and topics together. Filter by type before assuming a shape, or query the Follow model directly with followable_type.
  • Duplicate follows. UI double-clicks and retries can race. Confirm the migration includes a unique index on (follower_id, follower_type, followable_id, followable_type); if not, guard with isFollowing() inside a transaction or add the index yourself.
  • Self-follows. The package generally does not prevent a model from following itself. Add an explicit guard in your controller/policy if that state is invalid for your domain.
  • Orphan rows on delete. Polymorphic foreign keys cannot be constrained like normal FKs. Deleting a user or post can leave follows rows behind. Clean up in model deleting events or a scheduled prune, and be careful with soft deletes—soft-deleted models still appear in follower counts unless you scope queries.
  • followers_count only exists with withCount. Otherwise use $post->followers()->count(). Do not assume the attribute is always present.
  • Performance on hot paths. Follower counts and "is following" checks are frequent. Consider caching counts or denormalizing them if you render them on every page; the package itself does not cache.
  • Unsaved models. Calling follow() with a model that has no primary key will fail or store bad data. Persist models first.
  • Version compatibility. The last release is from mid-2023, so verify support against your Laravel/PHP version before adopting it in a new project, and run the test suite against your target framework.
  • Publish and inspect before trusting defaults. Check whether the package exposes a config for a custom Follow model or table name. If you need extra columns (e.g. created_at semantics, metadata), extending the model/config is usually cleaner than editing vendor migrations after the fact.
  • Extension point: custom follow model. If you need events, scopes, or extra attributes on follow records, point the package at your own model via its config (or override the traits) rather than scattering logic across controllers.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console