Recently, one of our clients requested we create a follow system on their platform, and not only that, but to also create a notifications popup, and a small activity feed.
We decided this could be a great opportunity to document the process, and share that information in hopes that it could help someone in the future.
We had to keep a few things in mind. First, it was quite possible that there might be more activities added to the feed in the future (as opposed to just “X followed Y”). Second, down the road, we’ll probably need to read & check for notifications in the background on our frontend, and not just once on page load.
With that in mind, we got to work!
Alright, so we need a way for users to follow other users. That’s clear. Upon any new follow, we also need to send the followed user a notification telling him someone followed him and that he’s one step closer to being famous. Finally, we also need to add that to some sort of activity feed so that other users can learn about it. Sounds about right.
Let’s start with a basic follow system, and we’ll take it from there. We’ll need a migration, model, controller, and two routes — one to follow, one to unfollow. The migration seems like a good place to start.
php artisan make:migration create_follows_table
We’ll simply need two columns, one to track the user that’s following, and another to track the user that’s being followed.
php artisan migrate
Next step, let’s add some handy methods to our User model to make everything smooth & clean. Open up your
User.php file and add the below code.
We’ve added a few things. First and foremost, we’ve defined two relationships:
following. By using
hasManyThrough we’ve basically told Laravel that we want them both to return User collections.
Next, we’ve also added an
isFollowing method that lets us know if a user is currently following another user. Finally, two more methods with
unfollow. We’ve also added a quick check for the
follow method to make sure we’re not trying to follow a user that’s already been followed previously — which will result in duplicate rows.
OK. Sounds good, now what? Think it’s time to add a Controller to the mix. Personally, we’re building this for an API, but feel free to tweak the below if you’re building a regular application.
php artisan make:controller Api/FollowController
And let’s put the following code inside our new
Pretty straightforward. We’ve created two methods, one that follows and one that unfollows. But notice we’re using a custom form request
FollowUnfollowRequest. Since we’re expecting some sort of parameters to accompany the request, let’s make sure to validate that.
php artisan make:request FollowUnfollowRequest
And inside that new
FollowUnfollowRequest.php file, let’s add some validations.
Again, hopefully pretty straightforward. We’re making sure the user sends a
user_id in the request body, making sure it exists, and finally that the user isn’t trying to follow himself (no free clout!).
Before we forget, we need to create a Follow model! Let’s do that.
php artisan make:model Follow
Looks good so far. Let’s add some routes to make sure everything is working properly, noting that we should only allow authenticated users to follow or unfollow. Let’s open up our
api.php routes file and add the below routes.
If we take this on a test run on Postman, we can see that it is working fine, and our
follows table is being properly filled. Perfect!
So what’s next? We’ve established that users can now follow and unfollow each other, which is a great first step. But now we need to track any follow activity on our platform, and then we also need to send the user a notification. Seems like we need to start with an Activities table so let’s do that.
php artisan make:migration create_activities_table
php artisan migrate
php artisan make:model Activity
Remember we said we’ll probably need to track more activities in the future? We’ve taken that into consideration. We’ve modeled our activities table to have a
type column, and a
target_id column. So imagine in the future we add some products that users can favorite, we can create an activity entry for that with
type: favorite and
target_id: product_id. But for now, we’re going to assume the only
type we have is
follow and that the
target_id is a user’s ID.
Next, let’s create the notification that will be sent to the user when he gets followed, after which we’ll start linking everything together.
php artisan make:notification NewFollow
We’ve set the notification driver to be the database, so we need to run a few more artisan commands to make sure our database can handle it.
php artisan notifications:table
php artisan migrate
And we’re set! Time to link everything together. We’re going to use Events, and the way it will work is that upon a new entry in the Follow table, we’ll trigger an event with two listeners: one to send the notification, and another to track the activity in the feed. To register the event, let’s go to our
EventServiceProvider.php file and add it to the
Then, we can run a quick and easy artisan command that will create all the files for us.
php artisan event:generate
We should now have 3 new files created:
NewFollowCreated event is fairly straightforward. We just need to save our Follow object to a property.
Second, let’s move on to our
CreateFollowActivity listener to track the follow event in our database.
Finally, we just need to send the user a notification now. So let’s hop on to the
CreateUserFollowNotification file to wrap things up.
Awesome! We’re almost there. We just need to make sure we’re triggering the Event when we create a new Follow entry. A small addition to our
Follow.php model and we should have that.
That should be it. Let’s run a quick test in Postman again and see if everything is in order, and we can move on.
The final piece of the puzzle is two more API routes: one to get the user notifications, and another to get an activity feed. Let’s set those up. We’ll need two controllers:
php artisan make:controller Api/FeedController
php artisan make:controller Api/NotificationsController
Both of these controllers will be pretty basic for the sake of the article, but obviously you can do whatever you want here.
Our feed controller will just return the activity feed with both user objects:
And our Notifications controller will also just return a basic array containing unread notifications with the object of the user that followed.
Finally, let’s add two more routes so they’re accessible, and that should be it!
There we have it folks. A pretty simple follow system with notifications and an activity feed.
This was obviously very stripped down, but hopefully just enough to give you an idea of how we approached the matter at hand. Hope you enjoyed it!