Laravel 5.8 REST CRUD API Tutorial – Build a CRM [PART 1]: Eloquent Models and Relationships

Laravel 5.8 is recently released with many improvements so we’ll be learning, throughout this tutorial how to create an example CRUD application from scratch. The application we’ll be building is a simple CRM with a MySQL database.
You can see this Upgrade Guide for instructions on how to upgrade an existing web application from Laravel 5.7 to Laravel 5.8
Tutorial Prerequisites
This tutorial has some prerequisites
You have at least PHP 7.1.3 installed on your development machine,
Working experience of PHP. The OpenSSL, PDO, Mbstring, Tokenizer, XML, Ctype, JSON and BCMath PHP extensions installed with your PHP version.
The MySQL database management system,
Composer (A PHP dependency management for PHP) installed on your machine. You can head to the official website for instructions how to download install it.
If you have these prerequisites, let’s get started by creating our first Laravel 5.8 project.
Creating a Laravel 5.8 Project with PHP Composer
Let’s use Composer to create a project based on Laravel 5.8. Open a new terminal and run the following command:
$ composer create-project –prefer-dist laravel/laravel laravel-crud
This command will automatically start installing the latest version of Laravel provided that you have the required dependencies of PHP for Laravel 5.8 installed on your system:
After finishing the installation process, navigate to the project’s folder:
$ cd ./laravel-crud
Next, serve your application using the artisan serve command:
$ php artisan serve
This will start a Laravel development server on the http://127.0.0.1:8000. Just leave it open as any changes we’ll be making will automatically get reloaded.
Configuring the MySQL Database
We’ll be using MySQL, the most popular database system used by PHP and Laravel developers so make sure you have created a database for your project. You can simply use the mysql client. Open a new terminal window and run the following command:
$ mysql -u root -p
You will get prompted for a password. Enter the one you submitted when you configured your MySQL installation and hit Enter.
When the mysql clients starts, enter the following SQL instruction to create a database:
mysql> create database l58db;
Note: You can also use phpMyAdmin to create and work with MySQL databases. phpMyAdmin is a free web interface tool created in PHP, intended to handle the administration of MySQL over the Web. It’s beginners friendlier tool that’s commonly used by PHP developers.
Now, let’s let Laravel know about our created database. Open the .env file in the root of your project and update the MySQL credentials with your own values: DB_CONNECTION=mysql DB_HOST=127.0.0.1 DB_PORT=3306 DB_DATABASE=l58db DB_USERNAME=root DB_PASSWORD=<YOUR_DATABASE_PASSWORD>
This will allow your application to connect to your MySQL database.
You can also configure the database connection in the config/database.php.
The database configuration for your application is located at config/database.php. In this file you may define all of your database connections, as well as specify which connection should be used by default. Examples for most of the supported database systems are provided in this file. The official docs
Next, let’s create the database tables using the following command:
$ php artisan migrate
Note: Until now, we didn’t create any models but Laravel makes use of multiple tables so we need to run the previous command to create them in our database. After we create our own models, we can run the artisan migrate command again to update the database structure.
This is the output of the command:
Migration table created successfully.
Migrating: 2014_10_12_000000_create_users_table
Migrated: 2014_10_12_000000_create_users_table
Migrating: 2014_10_12_100000_create_password_resets_table
Migrated: 2014_10_12_100000_create_password_resets_table
You can see that our project has already the users and password_resets tables.
The Application We’ll Be Building
We’ll be building a simple CRM application that allows sales managers to manage contacts, accounts, leads, opportunities, tasks and related activities. For the sake of simplicity we’ll try to add few interfaces as we can in our application. The main interface is a dashboard which contains the table of contacts and their status (lead, opportunity and customer). We’ll not add login and authentication in this tutorial as we’ll be the subject of another tutorial.
In our CRM database we’ll be making use of the following tables:
contacts — contains information about contacts/customers such as name, address, company/account, ,
activities — contains activities (phone calles, meetings and emails etc.) about the contacts,
accounts — contains information about contact companies,
users — contains information about the application users
We’ll also be using the following JOIN tables:
contact_status — contains contact status such as lead, opportunity or customer which indicates the stage in the sales cycle
activity_status — the activity status can be either pending, ongoing or completed,
contact_source — contains contact source.
The contacts table has the following fields:
id
title,
first name,
last name,
email,
phone,
address,
source_id,
date of first contact,
account_id,
status_id,
user_id,
The contact_status table has the following fields:
id,
status = (lead, proposal, customer, archived)
The contact_source table:
id,
name
The accounts table has the following fields:
id,
name,
description
The activities table has the following fields:
id,
date,
description,
contact_id
status_id The activity_status table has the following fields:
id,
status
Creating Laravel 5.8 Models
According to the database structure above, we’ll need to create the followng Eloquent models:
Contact
Account
Activity
ContactStatus
ContactSource
ActivityStatus
Head back to your terminal and run the following commands:
$ php artisan make:model Contact –migration
$ php artisan make:model Account –migration
$ php artisan make:model Activity –migration
$ php artisan make:model ContactStatus –migration
$ php artisan make:model ContactSource –migration
$ php artisan make:model ActivityStatus –migration
This will create models with the corresponding migrations files. The models exist in the app folder and you can find the migration files in the database/migrations folder.
The -m flag will also create the corresponding migration file for the model.
Next, in your terminal, run the following command to create the base tables:
$ php artisan migrate
You will get the following output:
Migration table created successfully.
Migrating: 2019_03_12_223818_create_contacts_table
Migrated: 2019_03_12_223818_create_contacts_table
Migrating: 2019_03_12_223832_create_accounts_table
Migrated: 2019_03_12_223832_create_accounts_table
Migrating: 2019_03_12_223841_create_activities_table
Migrated: 2019_03_12_223841_create_activities_table
Migrating: 2019_03_12_223855_create_contact_statuses_table
Migrated: 2019_03_12_223855_create_contact_statuses_table
Migrating: 2019_03_12_223904_create_contact_sources_table
Migrated: 2019_03_12_223904_create_contact_sources_table
Migrating: 2019_03_12_223912_create_activity_statuses_table
Migrated: 2019_03_12_223912_create_activity_statuses_table
In Laravel, you can specify the structure (table fields) in the migration files. Let’s start with the contacts table. Open the database/migrations/2019_03_12_223818_create_contacts_table.php file (the date prefix for the file will be different for you) and add the following changes:
public function up()
{
Schema::create(‘contacts’, function (Blueprint $table) {
$table->bigIncrements(‘id’);
$table->timestamps();
$table->string(‘title’);
$table->string(‘first_name’);
$table->string(‘last_name’);
$table->string(’email’);
$table->string(‘phone’);
$table->string(‘address’);
$table->date(‘date’);
$table->biginteger(‘user_id’)->unsigned(); $table->foreign(‘user_id’)->references(‘id’)->on(‘users’); });
}
Next, open the database/migrations/<YOUR_TIMESTAMP>_create_accounts_table.php file and change accordingly:
public function up()
{
Schema::create(‘accounts’, function (Blueprint $table) {
$table->bigIncrements(‘id’);
$table->timestamps();
$table->string(‘name’);
$table->description(‘description’); });
}
Next, open the database/migrations/<YOUR_TIMESTAMP>_create_activities_table.php file and change accordingly:
public function up()
{
Schema::create(‘activities’, function (Blueprint $table) {
$table->bigIncrements(‘id’);
$table->timestamps();
$table->string(‘description’);
});
}
Next, open the database/migrations/<YOUR_TIMESTAMP>_create_contact_statuses_table.php file and change accordingly:
public function up()
{
Schema::create(‘contact_statuses’, function (Blueprint $table) {
$table->bigIncrements(‘id’);
$table->timestamps();
$table->string(‘status’);
});
}
Next, open the database/migrations/<YOUR_TIMESTAMP>_create_contact_sources_table.php file and change accordingly:
public function up()
{
Schema::create(‘contact_sources’, function (Blueprint $table) {
$table->bigIncrements(‘id’);
$table->timestamps();
$table->string(‘name’);
});
}
Next, open the database/migrations/<YOUR_TIMESTAMP>_create_activity_statuses_table.php file and change accordingly:
public function up()
{
Schema::create(‘activity_statuses’, function (Blueprint $table) {
$table->bigIncrements(‘id’);
$table->timestamps();
$table->string(‘status’); });
}
You can see that we didn’t create any foreign keys between the tables. That’s because we need to avoid any issues to creating a foreign key to a table that doesn’t exist yet. The order of the migrations is important so you either make sure that the tables that are being referenced are created first or create the tables without any foreign keys and then add a migration to update the tables with the required relationships after the tables are created. Now, let’s create the update_contacts_table migration by running the following command:
$ php artisan make:migration update_contacts_table –table=contacts
Created Migration: 2019_03_12_235456_update_contacts_table
Open the database/migrations/<YOUR_TIMESTAMP>_update_contacts_table.php file and update accordingly:
public function up()
{
Schema::table(‘contacts’, function (Blueprint $table) {
$table->biginteger(‘source_id’)->unsigned(); $table->foreign(‘source_id’)->references(‘id’)->on(‘contact_sources’); $table->biginteger(‘account_id’)->unsigned(); $table->foreign(‘account_id’)->references(‘id’)->on(‘accounts’); $table->biginteger(‘status_id’)->unsigned(); $table->foreign(‘status_id’)->references(‘id’)->on(‘contact_statuses’);
});
}
We create three foreign key relationships to the contact_sources, accounts and contact_statuses tables.
Next, let’s create the update_activities_table migration by running the following command:
$ php artisan make:migration update_activities_table –table=activities
Created Migration: 2019_03_13_002644_update_activities_table
Open the database/migrations/<YOUR_TIMESTAMP>_update_activities_table.php file and update accordingly:
public function up()
{
Schema::table(‘activities’, function (Blueprint $table) {
$table->biginteger(‘contact_id’)->unsigned(); $table->foreign(‘contact_id’)->references(‘id’)->on(‘contacts’); $table->biginteger(‘status_id’)->unsigned(); $table->foreign(‘status_id’)->references(‘id’)->on(‘activity_statuses’); });
}
We create two foreign keys to the contacts and activity_statuses table.
Now, run the following command to migrate your database:
$ php artisan migrate
Implementing the Models
The Eloquent ORM included with Laravel provides a beautiful, simple ActiveRecord implementation for working with your database. Each database table has a corresponding "Model" which is used to interact with that table. Models allow you to query for data in your tables, as well as insert new records into the table. The official docs
We can interact with our database tables using the corresponding Eloquent models so we need implement the required methods in each model.
Defining the Relationships between Models
A contact belongs to a source, a status, an account and to a user and has many activities.
An account belongs to a user (i.e created by a user) and has many contacts.
An activity belongs to a status, a contact and to a user.
A contact status has many contacts.
A contact source has many contacts.
An activity status has many activities
Open the app/Account.php file and change accordingly:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Account extends Model
{
public function contacts(){
return $this->hasMany(‘App\Contact’);
}
public function user(){
return $this->belongsTo(‘App\User’);
}
}
Next, open the app/Activity.php file and change accordingly:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Activity extends Model
{
public function contact(){
return $this->belongsTo(‘App\Contact’);
}
public function status(){
return $this->belongsTo(‘App\ActivityStatus’);
}
public function user(){
return $this->belongsTo(‘App\User’);
}
}
Next, open the app/ActivityStatus.php file and change accordingly:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class ActivityStatus extends Model
{
public function activities(){
return $this->hasMany(‘App\Activiy’);
}
}
Next, open the app/Contact.php file and update accordingly:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Contact extends Model
{
protected $fillable = [
‘title’,
‘first_name’,
‘last_name’,
’email’,
‘phone’,
‘address’,
‘date’ ];
public function source(){
return $this->belongsTo(‘App\ContactSource’);
}
public function status(){
return $this->belongsTo(‘App\ContactStatus’);
}
public function account(){
return $this->belongsTo(‘App\Account’);
}
public function user(){
return $this->belongsTo(‘App\User’);
}
public function activities(){
return $this->hasMany(‘App\Contact’);
}
}
Next, open the app/ContactSource.php file and update accordingly:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class ContactSource extends Model
{
public function contacts(){
$this->hasMany(‘App\Contact’);
}
}
Next, open the app/ContactStatus.php file and update accordingly:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class ContactStatus extends Model
{
//
public function contacts(){
$this->hasMany(‘App\Contact’);
}
}
Finally, open the app/User.php file and update as follows:
<?php
namespace App;
use Illuminate\Notifications\Notifiable;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable
{
use Notifiable;
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [
‘name’, ’email’, ‘password’,
];
/**
* The attributes that should be hidden for arrays.
*
* @var array
*/
protected $hidden = [
‘password’, ‘remember_token’,
];
/**
* The attributes that should be cast to native types.
*
* @var array
*/
protected $casts = [
’email_verified_at’ => ‘datetime’,
];
public function contacts(){
$this->hasMany(‘App\Contact’);
}
public function activities(){
return $this->hasMany(‘App\Activiy’);
}
public function accounts(){
return $this->hasMany(‘App\Account’);
}
}
Next we’ll be creating the REST API controllers.
via Planet MySQL
Laravel 5.8 REST CRUD API Tutorial – Build a CRM [PART 1]: Eloquent Models and Relationships