Laravel is undoubtedly one of the best things to happen to PHP and you’ve probably guessed based on my post history, I really like it and want to expose more people to its cool features and help the PHP ecosystem move away from the stigma of all PHP code being bad.
Today, in this tutorial like post I will be explaining how you can add in a user following system like Twitter, Quora or any other social network that allows you to follow another user and have users follow you.
What we will be using
There are 3 different components of Laravel we will be using which are;
- Migrations (for defining our schemas)
- Seeding (for populating our database with dummy content follows)
- Models using Eloquent ORM (for defining the relationships)
This article will assume you already have Laravel downloaded and you’re using the command line and Artisan for generating the needed files. If you need help for these steps, please read the manual on the official Laravel website.
Creating the migrations
Create the users table
php artisan migrate:make create_users_table
This should add a file prefixed by a date in the folder: app/database/migrations – you will then want to open up this table and add a few basic fields, we’re not going to handle logging in or any kind of authentication aspect, just how to set everything up.
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
class CreateUsersTable extends Migration {
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('users', function (Blueprint $table)
{
$table->increments('id');
$table->string('username', 255);
$table->string('email', 255);
$table->string('password', 255);
$table->string('full_name');
$table->timestamps();
$table->softDeletes();
$table->index('id');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::drop('users');
}
}
Create the followers table
php artisan migrate:make create_followers_table
This should add another file prefixed by a date in the folder: app/database/migrations – you will then want to open up this table and add a few basic fields, we’re not going to handle logging in or any kind of authentication aspect, just how to set everything up.
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateFollowersTable extends Migration {
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('followers', function ($table)
{
$table->integer('user_id')->unsigned();
$table->integer('follow_id')->unsigned();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::drop('followers');
}
}
Creating the seeds
Now that we have our basic following schema setup with users and a followers table, we will now add in some basic values and mock users.
Unlike our migrations, we are going to create our seeds manually because they require more manual development and can’t really be automated all too much on the command line.
All of our seed files are going to go into the following folder: app/database/seeds and follow a camelCase format. The seeds we will be creating are: UserTableSeeder.php and FollowerTableSeeder.php
Create the user table seeder: app/database/seeds/UserTableSeeder.php
<?php
class UserTableSeeder extends Seeder {
public function run()
{
// Empty all previous records out
DB::table('users')->delete();
User::create(array(
'username' => 'username1',
'email' => 'foo@bar.com',
'password' => 'password',
'full_name' => 'User One'
));
User::create(array(
'username' => 'username2',
'email' => 'foo2@bar.com',
'password' => 'password',
'full_name' => 'User Two'
));
User::create(array(
'username' => 'username3',
'email' => 'foo3@bar.com',
'password' => 'password',
'full_name' => 'User Three'
));
User::create(array(
'username' => 'username4',
'email' => 'foo4@bar.com',
'password' => 'password',
'full_name' => 'User Four'
));
}
}
Create the follow table seeder: app/database/seeds/FollowerTableSeeder.php
<?php
class FollowerTableSeeder extends Seeder {
public function run()
{
// Empty all previous records out
DB::table('followers')->delete();
// User with ID 1 is following user with ID 2
Follower::create(array(
'user_id' => '1',
'follower_id' => '2',
));
// User with ID 2 is following user with ID 3
Follower::create(array(
'user_id' => '2',
'follower_id' => '3',
));
// User with ID 3 is following user with ID 4
Follower::create(array(
'user_id' => '3',
'follower_id' => '4',
));
// User with ID 4 is following user with ID 1
Follower::create(array(
'user_id' => '4',
'follower_id' => '1',
));
}
}
Call our seeders
In the app/database/seeds folder you should see a class already there called, “DatabaseSeeder.php”, open up that file and you should see a method called run()
Inside of this method, add the following calls to our created seeds:
$this->call('UserTableSeeder');
$this->command->info('User table seeded!');
$this->call('FollowerTableSeeder');
$this->command->info('Follower table seeded!');
You will notice the two calls above map to the name of our created seed files and the classname itself.
Creating our models
We have our migrations aka schema setup, we have our seeds as well and now we need our models to complete the picture. Fortunately for us, Laravel comes with a User.php model already created, so we just need to add a couple of methods for relationships to the follower table.
Edit app/models/User.php
In the user model we want to add a couple of methods.
// This function allows us to get a list of users following us
public function followers()
{
return $this->belongsToMany('User', 'followers', 'follow_id', 'user_id')->withTimestamps();
}
// Get all users we are following
public function following()
{
return $this->belongsToMany('User', 'followers', 'user_id', 'follow_id')->withTimestamps();
}
Running our migrations and seeds
Now we have everything in place, lets run our migrations and seeds to populate our database. This step assumes you’ve configured a MySQL database or equivelent with Laravel.
Run our migrations
php artisan migrate
Seed our database
php artisan db:seed
Using it
I won’t go into too much detail as to how this works as I don’t believe providing all of the code is of any help to someone learning. See below for an example controller of the follower system working, forgoing any kind of authentication of course.
In-case you also didn’t know, the "follow_id"
in the followers table is the user being followed, the "user_id"
is the person doing the following. So using the seed data above of user ID 1 being username1 and user ID 2 being username 2, if user one is to follow user two, the user_id
is 1 and the follow_id
value is 2.
<?php
class FollowerController extends BaseController {
// Make user one follow user 2 (does not check if already following)
public function userOneFollowsTwo()
{
// Find user with ID 1
$user1 = User::find(1);
// Find user with ID 2
$user2 = User::find(2);
if ($user1 && $user2) {
$user1->following()->save($user2);
}
}
// Get all user two followers (if previous method run it should return user 1)
public function userTwoFollowers()
{
// Find user with ID 2
$user2 = User::find(2);
if ($user2) {
foreach ($user2->followers AS $follower) {
echo $follower->username . "<br />";
}
}
}
}
Hello, I am trying your method. It doesn’t work, I believe the relationships you suggest for users are wrong. All it does is return Class ‘user’ not found.