3. Models & migrations - adaptdk/developer-meeting-nova GitHub Wiki

Our models

Our new company will have the following models:

  • Brand (the brand of cars)
  • Color (color of the car)
  • Seller (our staff)
  • Car (the cars we have for sale)
  • Dealership (physical places where the cars are on display)
  • Customer (the schmocks that will buy the used cars)
  • Order (the final document for the customer)

Setting up the models

Now we can start setting up our model by using Laravels CLI tool - Artisan.

By add the -m it also creates migration-files for creating the database schema.

php artisan make:model Brand -m
php artisan make:model Color -m
php artisan make:model Car -m
php artisan make:model Dealership -m
php artisan make:model Seller -m
php artisan make:model Customer -m
php artisan make:model Order -m

This will create 7 models in your /app folder and the same number of migration files in /database/migrations folder.

Migration setup for Brand and Color

Brand

Brand and color are simple data tables that will be part of the description of the car.

Add a name field for the brand in the migration file for the brand.

Since most of the boilerplate code is done for you, only add the following line in between the Schema::create part:

$table->string('name');

Your migration file should look like this:

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreateBrandsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('brands', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->string('name');
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('brands');
    }
}
 

Color

Add the same column to Color migration file

$table->string('name');

Your color migration file should look like this:

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreateColorsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('colors', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->string('name');
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('colors');
    }
}

Migration setup for Dealership

The car dealship is a physical place for the customers to see the cars for sale. There can be multiple points of sale.

  • internal_name (string)
  • street_name (string)
  • city (string)

Translated into code add this to your Schema-create part

$table->string('internal_name');
$table->string('street_name');
$table->string('city');

Your migration file will look like this :

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreateDealershipsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('dealerships', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->string('internal_name');
            $table->string('street_name');
            $table->string('city');
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('dealerships');
    }
}

Migration setup for Car

Car

Car model will contain relationships to Brand and Color. A car can be of a brand and have one color (for simplicity we selected that it only has a one color).

As it is a physical item, we need to place it in a Dealership.

We also need a model type, price and a description for it.

  • brand_id
  • color_id
  • dealership_id
  • model_type
  • description
  • sold

In your migration file add these fields:

$table->unsignedBigInteger('brand_id');
$table->unsignedBigInteger('color_id');
$table->unsignedBigInteger('dealership_id');
$table->string('model_type');
$table->longText('description');
$table->boolean('sold')->default(false);

As the migrations are made with bigIncrements field, we also use * unsignedBigInteger* as foreign field types.

We also set up a boolean value to tell whether a car is sold or not. Default is set to false.

Your cars table will look like this :

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreateCarsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('cars', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->unsignedBigInteger('brand_id');
            $table->unsignedBigInteger('color_id');
            $table->unsignedBigInteger('dealership_id');
            $table->string('model_type');
            $table->longText('description');
            $table->boolean('sold')->default(false);
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('cars');
    }
}

Migration setup for Seller

A seller can work shifts in different Dealership locations. First we just setup our plain seller model by adding a name to our migration file in the Schema::create part.

$table->string('name');

Your Seller model should look like this:

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreateSellersTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('sellers', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->string('name');
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('sellers');
    }
}

Dealership to Seller - Many to many

A seller can be attached to many dealership locations as well as a dealshipership can have many sellers.

Many-to-many relationship migration

When you create a model you use a singlar term, e.g. Brand. If you look into you migration files all the tables are created with plural name, in the case brands

Adding a pivot table

To handle many-to-many relationship we use a pivot table. To create such a table we need to create the table ourselves using artisan:

php artisan make:migration create_dealership_seller_table --create=dealership_seller

To get the full force of pivot tables in Laravel we use the singular form of each model with a underscore inbetween. The model table must be ordered in an alphabetical order, so dealership comes before seller.

To the newly created migration file you add the following two columns :

$table->unsignedBigInteger('dealership_id');
$table->unsignedBigInteger('seller_id');

Your migration file should look like this :

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreateDealershipSellerTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('dealership_seller', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->unsignedBigInteger('dealership_id');
            $table->unsignedBigInteger('seller_id');
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('dealership_seller');
    }
}

Migration setup for Customer

We make a very simple customer model, so we just need a name

$table->string('name');

Your migration file will look like this :

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreateCustomersTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('customers', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->string('name');
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('customers');
    }
}

Migration setup for Order

We want the following info for an order

  • Who bought the car
  • Which car
  • Who sold the car
  • Which dealership got the order
  • How long can the customer bitch about the car

So we add the following fields for an order :

$table->unsignedBigInteger('customer_id');
$table->unsignedBigInteger('car_id');
$table->unsignedBigInteger('seller_id');
$table->unsignedBigInteger('dealership_id');
$table->dateTime('warranty_expires');

Your migration file for an order will look like this

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreateOrdersTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('orders', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->unsignedBigInteger('customer_id');
            $table->unsignedBigInteger('car_id');
            $table->unsignedBigInteger('seller_id');
            $table->unsignedBigInteger('dealership_id');
            $table->dateTime('warranty_expires');
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('orders');
    }
}

Migrating

Migrating is done by calling the artisan command like this

artisan migrate

This will create the tables in your database. It will also writes which migration files has been added in the migration-table.

If something goes wrong or you have forgot some of the fields you can do a rollback.

artisan migrate:rollback

More info on fresh, refresh and multiple rollbacks.

For additional info on how you run migrations, do a full refresh and related info read more at Offical Laravel Documentation