An introduction to Laravel ORM : Eloquent

Sep 11, 2018 by Thibault Debatty - 328 views

https://cylab.be/blog/9/an-introduction-to-laravel-orm-eloquent

When working with an object oriented language, like PHP, Java or Python, an Object-Relational Mapping (ORM) tool allows to automatically convert model objects into rows in a database and vice-versa. It allows to easily save objects in a database, without worrying about writing appropriate SQL requests.

In most ORM frameworks, like Java Hibernate or PHP Doctrine, the developer has to define the fields of its model classes. From the code and documentation blocks, the ORM will infer the name of the table where these objects have to be saved, as wel as the name and type of each column. The example below is copied from the documentation of Doctrine ORM:

// src/Product.php
class Product
{
    /**
     * @var int
     */
    protected $id;
    /**
     * @var string
     */
    protected $name;

    public function getId()
    {
        return $this->id;
    }

    public function getName()
    {
        return $this->name;
    }

    public function setName($name)
    {
        $this->name = $name;
    }
}

https://www.doctrine-project.org/projects/doctrine-orm/en/2.6/tutorials/getting-started.html#starting-with-the-product-entity

The laravel framework comes with a built-in ORM, called Eloquent, that works in the opposite way: Eloquent infers the fields of your objects from the columns of the database table.

As a consequence, your model classes (located in the app directory) usually contain no field. They are only used to define methods and relations:

namespace App;

use Illuminate\Database\Eloquent\Model;

/**
 * Eloquent expects that the corresponding table is books 
 * (plural lower case version of the class name)
 */
class Book extends Model {

    /* 
     * Defines a relation
     * From this, eloquent expects that the books table has a column 
     * named author_id
     */
    public function author() {
        return $this->belongsTo("App\User");
    }

    /*
     * Eloquent expects that the pages table has a column book_id
     */
    public function pages() {
        return $this->hasMany("App\Page");
    }   
}

You can check Laravel documentation for details about Eloquent relations.

Laravel IDE Helper

This can disturb the auto-complete function of some IDE's (including NetBeans). Luckily, there is a laravel extension called Laravel IDE Helper to solve this. It reads the structure of your database and writes the documentation blocks required by the IDE to provide you autocomplete information.

You can install it using composer:

composer require barryvdh/laravel-ide-helper
composer require doctrine/dbal

Each time you modify the structure of your database, you can now run ide-helper to update the autocomplete information:

php artisan ide-helper:models

Laravel IDE helper is also able to generate required doc blocks to enable autocomplete with other Laravel facade classes:

php artisan ide-helper:generate

Migrations

Laravel also provides a tool to design the tables of your database. It allows to use code to create the tables of your database, without the need for a tool like PhpMyAdmin. Each modification to the database structure is described in a so-called migration, located in directory database/migrations.

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

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

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

You can create a migration to create a new table by typing

php artisan make:migration <name of migration> 
  --create=<name of table>

Or you can create a migration to modify an existing table by typing

php artisan make:migration <name of migration> 
  --table=<name of table>

For example:

php artisan make:migration books_add_author_id 
  --table=books

Once your migration is ready, you can apply it by typing

php artisan migrate

This will create the required tables and columns in your database. You can check Laravel documentation to get more information about migrations

Pay attention: if you are working in a team (using GIT for example), do never rename or modify a migration file once it is pushed to the repository! The migrate command keeps track of the migrations that have already been applied. It does not execute the same migration twice.

Hence, if you modify a migration, your modifications will not be applied and your colleagues will not see the modifications you made.

If you rename a migration, it will cause errors like cannot create table: table already exists as migrate thinks this migration has not been executed yet and tries to create the same table twice...