Laravel — P29: Models Intro

Laravel Models Unveiled: Your Gateway to Data Interaction

After spending an entire article learning about migrations, it’s only natural that the next one is going to be focused on Models.

What is a Model?

A Model is just a class that ties into a table within the database. By convention, tables are plural and Models are singular versions of the table name. For example, the tests table should have a Test model associated with it.

The Test model knows how to communicate with the tests table and can add, update, get, or delete data from the table.

How does the Model know to interact with the specific table? It’s thanks to Laravel’s Eloquent ORM (object-relational mapper).

Laravel Models live in the app\Models directory. Once you create the Model, it’s a basic shell with a ton of functionality. It has this functionality because it extends the Illuminate\Database\Eloquent\Model class.

How Do You Create a Model?

We already have a tests migration. We simply want to create a Model for it. Remember that the Model will be the singular version of our table name: Test. Run the following artisan command.

php artisan make:model Test

Open the app/Models/Test.php file and you should see the following code in there.

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Test extends Model
{
    use HasFactory;
}

We’ll go over factories soon. You can just ignore it for now. But overall, that’s it. You now have a ton of functionality. Let’s do some basic CRUD operations on our Test model.

Remember our tests schema? You’ll need to know that. I’m going to remove the foreignId constraint to make this a little easier and rerun the migrations: php artisan migrate:fresh.

<?php
Schema::create('tests', function (Blueprint $table) {
    $table->id();
    $table->string('first_name');
    $table->string('last_name');
    $table->foreignId('user_id')->constrained();
    $table->string('email')->unique();
    $table->text('bio');
    $table->integer('age');
    $table->float('money');
    $table->boolean('is_active');
    $table->timestamps();
});

We have already created a TestController in an earlier article. If you need a refresher, you can read about it here.

https://medium.com/geekculture/laravel-p24-controllers-intro-8e80c9f9658e
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class TestController extends Controller
{
    public function index()
    {
        return [
            [
                "make" => "Chevrolet",
                "model" => "Corvette",
            ],
            [
                "make" => "Porsche",
                "model" => "911 GT3",
            ],
        ];
    }

    public function show()
    {
        return [
            "make" => "Porsche",
            "model" => "911 GT3",
        ];
    }

    public function edit($id)
    {
        return "If we were editing, this would be for " . $id;
    }

    public function delete($user_id, $user_name)
    {
        return "Record " . $user_id . " has been deleted for " . $user_name;
    }
}

It already contains three methods:

  • index — show all records
  • show — show one record
  • delete — delete a record

We just need to add:

  • insert — to insert a new record
  • update — to update a record

Realistically, we also need to cover showing forms for it all, but I’ll leave that off for a later time when we discuss resource controllers and look at forms.

Creating the Routes

Let’s get the routes out of the way first. We know that we need routes to point to each of the methods in our TestController.

<?php
use App\Http\Controllers\TestController;

Route::get('/test-model/store', [TestController::class, 'store']);
Route::get('/test-model/', [TestController::class, 'index']);
Route::get('/test-model/show/{id}', [TestController::class, 'show']);
Route::get('/test-model/update/{id}', [TestController::class, 'update']);
Route::get('/test-model/delete/{id}', [TestController::class, 'destroy']);

It’s so nice to see a clean route file. We’re going to be passing the id of the record that we want to update to our showupdate, and delete methods.

Creating a New Record

To insert a new record, we simply create a new instance of our Test model, set the properties (i.e. table column names), and save() it. I’m going to add a timestamp to our email since it has to be unique each time.

<?php

namespace App\Http\Controllers;

use App\Models\Test;
use Illuminate\Http\Request;

class TestController extends Controller
{
    public function store()
    {
        $test = new Test;

        $test->first_name = "Dino";
        $test->last_name = "Cajic";
        $test->phone = "4443335555";
        $test->email = "dino+" . time() . "@example.com";
        $test->bio = "This is the story of Dino";
        $test->age = 102;
        $test->money = 100;
        $test->is_active = true;

        $test->save();

        return $test;
    }
}

I’m also going to return our $test object to see what it looks like. We just need to create a route. Visiting our route, we get the following result.

{
"first_name": "Dino",
"last_name": "Cajic",
"phone": "4443335555",
"email": "dino+1673639389@example.com",
"bio": "This is the story of Dino",
"age": 102,
"money": 100,
"is_active": true,
"updated_at": "2023-01-13T19:49:49.000000Z",
"created_at": "2023-01-13T19:49:49.000000Z",
"id": 3
}

Viewing All Records

What is the SQL query to return all records? Who cares. Eloquent allows us to return all the records with one line of code.

<?php

namespace App\Http\Controllers;

use App\Models\Test;
use Illuminate\Http\Request;

class TestController extends Controller
{
    public function index()
    {
        return Test::all();
    }

    // ...
}
Time to see the results.
[
{
"id": 1,
"first_name": "Dino",
"last_name": "Cajic",
"email": "dino@example.com",
"phone": "4443335555",
"bio": "This is the story of Dino",
"age": 102,
"money": 100,
"is_active": 1,
"created_at": "2023-01-13T19:48:24.000000Z",
"updated_at": "2023-01-13T19:48:24.000000Z"
},
{
"id": 3,
"first_name": "Dino",
"last_name": "Cajic",
"email": "dino+1673639389@example.com",
"phone": "4443335555",
"bio": "This is the story of Dino",
"age": 102,
"money": 100,
"is_active": 1,
"created_at": "2023-01-13T19:49:49.000000Z",
"updated_at": "2023-01-13T19:49:49.000000Z"
}
]

It’s an array of JSON objects. How nice is that?

Showing a Single Record

Our show method needs to accept an id that corresponds to a record in the tests table. In my instance, we have 1 and 3 so I’m going to pass 1 to our show method: http://0.0.0.0/test-model/show/1.

What does our show method need to look like? Is it yet another complex SQL query? Nope.

<?php

namespace App\Http\Controllers;

use App\Models\Test;
use Illuminate\Http\Request;

class TestController extends Controller
{
    // ...

    public function show($id)
    {
        return Test::find($id);
    }

    // ...
}

You simply use the find method and pass the $id. It knows what to do. Are there other ways to do this? Of course, but we won’t discuss those just yet.

Updating a Record

To update a record, we first need to find it and then just change the property that we want to update. Once we update it, we save it and we’re done.

<?php

namespace App\Http\Controllers;

use App\Models\Test;
use Illuminate\Http\Request;

class TestController extends Controller
{
    // ...

    public function update($id)
    {
        $test = Test::find($id);
        $test->phone = "5554443333";
        $test->save();

        return $test;
    }
}

Deleting a Record

Finally, we need to delete a record. To delete a record, we again need the record id and use the Eloquent model to process it.

<?php

namespace App\Http\Controllers;

use App\Models\Test;
use Illuminate\Http\Request;

class TestController extends Controller
{
    // ...

    public function destroy($id)
    {
        Test::destroy($id);

        return $id . " has been deleted";
    }
}

Summary

You might have noticed that once we created our Test model, we did not touch our Model code whatsoever. We simply worked on our TestController. Here’s the full code.

<?php

namespace App\Http\Controllers;

use App\Models\Test;
use Illuminate\Http\Request;

class TestController extends Controller
{
    public function index()
    {
        return Test::all();
    }

    public function show($id)
    {
        return Test::find($id);
    }

    public function store()
    {
        $test = new Test;

        $test->first_name = "Dino";
        $test->last_name = "Cajic";
        $test->phone = "4443335555";
        $test->email = "dino+" . time() . "@example.com";
        $test->bio = "This is the story of Dino";
        $test->age = 102;
        $test->money = 100;
        $test->is_active = true;

        $test->save();

        return $test;
    }

    public function update($id)
    {
        $test = Test::find($id);

        $test->phone = "5554443333";

        $test->save();

        return $test;
    }

    public function destroy($id)
    {
        Test::destroy($id);

        return $id . " has been deleted";
    }
}

That’s about as much as we need to know about models to keep us going. Models have a ton of functionality, like deleting multiple records, selecting statements based on conditions, batch insertions, joins, etc. Next, we’ll look at automating the population of our tables with test data.

Laravel Series

Continue your Laravel Learning.

Laravel — P28: Migrations

Evolving Your Laravel Projects: Mastering Migrations

Laravel – P28: Migrations

Ensure your Laravel database evolves with your app. Learn migrations for seamless updates and rollback capabilities. Start now!

Laravel — P29: Models Intro

Laravel Models Unveiled: Your Gateway to Data Interaction

Laravel – P29: Models

Dive into Laravel models to interact with database effortlessly. Discover how to utilize models for efficient data handling & retrieval.

Laravel — P30: Factories

Efficient Testing in Laravel: The Role of Factories

Laravel – P30: Factories

Master Laravel factories for rapid testing & data seeding. Learn how to create realistic data models for development & testing efficiency.

Leave a Reply