Laravel Models Unveiled: Your Gateway to Data Interaction
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.
<?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 recordsshow
— show one recorddelete
— delete a record
We just need to add:
insert
— to insert a new recordupdate
— 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 show
, update
, 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();
}
// ...
}
[
{
"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.
Evolving Your Laravel Projects: Mastering Migrations
Ensure your Laravel database evolves with your app. Learn migrations for seamless updates and rollback capabilities. Start now!
Laravel Models Unveiled: Your Gateway to Data Interaction
Dive into Laravel models to interact with database effortlessly. Discover how to utilize models for efficient data handling & retrieval.
Efficient Testing in Laravel: The Role of Factories
Master Laravel factories for rapid testing & data seeding. Learn how to create realistic data models for development & testing efficiency.