6_Eloquent Getting Started
6_Eloquent Getting Started
# Introduction
Laravel includes Eloquent, an object-relational mapper (ORM) that makes it enjoyable to
interact with your database. When using Eloquent, each database table has a corresponding
"Model" that is used to interact with that table. In addition to retrieving records from the
database table, Eloquent models allow you to insert, update, and delete records from the table
as well.
Before getting started, be sure to configure a database connection in your application's
config/database.php configuration file.
# Generating Model Classes
To get started, let's create an Eloquent model. Models typically live in the app\Models
directory and extend the Illuminate\Database\Eloquent\Model class.
You may use the make:model Artisan command to generate a new model:
php artisan make:model Flight
If you would like to generate a database migration when you generate the model, you may use
the --migration or -m option:
php artisan make:model Flight –migration
Table Names
After glancing at the example above, you may have noticed that we did not tell Eloquent which
database table corresponds to our Flight model. By convention, the "snake case", plural name
of the class will be used as the table name unless another name is explicitly specified. So, in
this case, Eloquent will assume the Flight model stores records in the flights table, while an
AirTrafficController model would store records in an air_traffic_controllers table.
1
If your model's corresponding database table does not fit this convention, you may manually
specify the model's table name by defining a table property on the model:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
Primary Keys
Eloquent will also assume that each model's corresponding database table has a primary key
column named id. If necessary, you may define a protected $primaryKey property on your
model to specify a different column that serves as your model's primary key:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Flight extends Model
{
/**
* The primary key associated with the table.
*
* @var string
*/
protected $primaryKey = 'flight_id';
2
}
UUID and ULID Keys
Instead of using auto-incrementing integers as your Eloquent model's primary keys, you may
choose to use UUIDs instead. UUIDs are universally unique alpha-numeric identifiers that
are 36 characters long.
If you would like a model to use a UUID key instead of an auto-incrementing integer key, you
may use the Illuminate\Database\Eloquent\Concerns\HasUuids trait on the model. Of course,
you should ensure that the model has a UUID equivalent primary key column:
use Illuminate\Database\Eloquent\Concerns\HasUuids;
use Illuminate\Database\Eloquent\Model;
// ...
}
$article = Article::create(['title' => 'Traveling to Europe']);
$article->id; // "8f8e8478-9035-4d23-b9a7-62f4d2612ce5"
Timestamps
By default, Eloquent expects created_at and updated_at columns to exist on your model's
corresponding database table. Eloquent will automatically set these column's values when
models are created or updated. If you do not want these columns to be automatically
managed by Eloquent, you should define a $timestamps property on your model with a value
of false:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
3
* Indicates if the model should be timestamped.
*
* @var bool
*/
public $timestamps = false;
}
Database Connections
By default, all Eloquent models will use the default database connection that is configured for
your application. If you would like to specify a different connection that should be used when
interacting with a particular model, you should define a $connection property on the model:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
4
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
/**
* Bootstrap any application services.
*/
public function boot(): void
{
5
Model::preventLazyLoading(! $this->app->isProduction());
}
# Retrieving Models
Once you have created a model and its associated database table, you are ready to start
retrieving data from your database. You can think of each Eloquent model as a powerful query
builder allowing you to fluently query the database table associated with the model. The
model's all method will retrieve all of the records from the model's associated database table:
use App\Models\Flight;
foreach (Flight::all() as $flight) {
echo $flight->name;
}
Building Queries
$flights = Flight::where('active', 1)
->orderBy('name')
->take(10)
->get();
Collections
As we have seen, Eloquent methods like all and get retrieve multiple records from the
database. However, these methods don't return a plain PHP array. Instead, an instance of
Illuminate\Database\Eloquent\Collection is returned.
The Eloquent Collection class extends Laravel's base Illuminate\Support\Collection class,
which provides a variety of helpful methods for interacting with data collections. For example,
the reject method may be used to remove models from a collection based on the results of an
invoked closure:
$flights = Flight::where('destination', 'Paris')->get();
$flights = $flights->reject(function (Flight $flight) {
return $flight->cancelled;
});
Chunking Results
Your application may run out of memory if you attempt to load tens of thousands of Eloquent
records via the all or get methods. Instead of using these methods, the chunk method may be
used to process large numbers of models more efficiently.
6
The chunk method will retrieve a subset of Eloquent models, passing them to a closure for
processing. Since only the current chunk of Eloquent models is retrieved at a time, the chunk
method will provide significantly reduced memory usage when working with a large number
of models:
use App\Models\Flight;
use Illuminate\Database\Eloquent\Collection;
Flight::chunk(200, function (Collection $flights) {
foreach ($flights as $flight) {
// ...
}
});
The first argument passed to the chunk method is the number of records you wish to receive
per "chunk". The closure passed as the second argument will be invoked for each chunk that
is retrieved from the database.
Chunk Using Lazy Collections
The lazy method works similarly to the chunk method in the sense that, behind the scenes, it
executes the query in chunks. However, instead of passing each chunk directly into a callback
as is, the lazy method returns a flattened LazyCollection of Eloquent models, which lets you
interact with the results as a single stream:
use App\Models\Flight;
foreach (Flight::lazy() as $flight) {
// ...
}
Cursors
Similar to the lazy method, the cursor method may be used to significantly reduce your
application's memory consumption when iterating through tens of thousands of Eloquent
model records. The cursor method will only execute a single database query.
use App\Models\Flight;
foreach (Flight::where('destination', 'Zurich')->cursor() as $flight) {
// ...
}
Advanced Subqueries
Using the subquery functionality available to the query builder's select and addSelect methods,
we can select all of the destinations and the name of the flight that most recently arrived at that
destination using a single query:
7
use App\Models\Destination;
use App\Models\Flight;
return Destination::addSelect(['last_flight' => Flight::select('name')
->whereColumn('destination_id', 'destinations.id')
->orderByDesc('arrived_at')
->limit(1)
])->get();
# Retrieving Single Models / Aggregates
In addition to retrieving all of the records matching a given query, you may also retrieve single
records using the find, first, or firstWhere methods. Instead of returning a collection of models,
these methods return a single model instance:
use App\Models\Flight;
// Retrieve a model by its primary key...
$flight = Flight::find(1);
// Retrieve the first model matching the query constraints...
$flight = Flight::where('active', 1)->first();
// Alternative to retrieving the first model matching the query constraints...
$flight = Flight::firstWhere('active', 1);
The firstOrNew method, like firstOrCreate, will attempt to locate a record in the database
matching the given attributes. However, if a model is not found, a new model instance will be
returned. Note that the model returned by firstOrNew has not yet been persisted to the database.
You will need to manually call the save method to persist it:
use App\Models\Flight;
8
'name' => 'London to Paris'
]);
// Retrieve flight by name or create it with the name, delayed, and arrival_time attributes...
$flight = Flight::firstOrCreate(
['name' => 'London to Paris'],
['delayed' => 1, 'arrival_time' => '11:30']
);
// Retrieve flight by name or instantiate with the name, delayed, and arrival_time attributes...
$flight = Flight::firstOrNew(
['name' => 'Tokyo to Sydney'],
['delayed' => 1, 'arrival_time' => '11:30']
);
Retrieving Aggregates
When interacting with Eloquent models, you may also use the count, sum, max, and other
aggregate methods provided by the Laravel query builder. As you might expect, these
methods return a scalar value instead of an Eloquent model instance:
$count = Flight::where('active', 1)->count();
$max = Flight::where('active', 1)->max('price');
9
<?php
namespace App\Http\Controllers;
use App\Http\Controllers\Controller;
use App\Models\Flight;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
10
Mass Assignment
You may use the create method to "save" a new model using a single PHP statement. The
inserted model instance will be returned to you by the method:
use App\Models\Flight;
$flight = Flight::create([
'name' => 'London to Paris',
]);
However, before using the create method, you will need to specify either a fillable or guarded
property on your model class.
Upserts
Eloquent's upsert method may be used to update or create records in a single, atomic operation.
Flight::upsert([
['departure' => 'Oakland', 'destination' => 'San Diego', 'price' => 99],
['departure' => 'Chicago', 'destination' => 'New York', 'price' => 150]
], uniqueBy: ['departure', 'destination'], update: ['price']);
# Deleting Models
To delete a model, you may call the delete method on the model instance:
use App\Models\Flight;
$flight = Flight::find(1);
$flight->delete();
Soft Deleting
In addition to actually removing records from your database, Eloquent can also "soft delete"
models. When models are soft deleted, they are not actually removed from your database.
Instead, a deleted_at attribute is set on the model indicating the date and time at which the
model was "deleted". To enable soft deletes for a model, add the
Illuminate\Database\Eloquent\SoftDeletes trait to the model:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
11
class Flight extends Model
{
use SoftDeletes;
}
Querying Soft Deleted Models
As noted above, soft deleted models will automatically be excluded from query results.
However, you may force soft deleted models to be included in a query's results by calling the
withTrashed method on the query:
use App\Models\Flight;
$flights = Flight::withTrashed()
->where('account_id', 1)
->get();
# Pruning Models
# Replicating Models
# Query Scopes
Global Scopes
Local Scopes
# Comparing Models
# Events
Using Closures
Observers
Muting Events
12