Laravel Eloquent is a powerful ORM that uses Active Record Pattern which is a technique to wrap database into objects. By using eloquent, we can present data stored in a database table as a class and records as objects. So each database table has “Model” which is used to interact with the table. We can use eloquent to create, edit, query and delete records easily rather than raw SQL. It makes the code easily readable and much cleaner.
And it’s not enough; Laravel Eloquent ORM has built-in relationships that allows us to not only manipulate one table in the database but also we can manipulate all related data.
So let’s get started. Eloquent models live in app directory and all eloquent models extend Illuminate\Database\Eloquent\Model
.
Creating a model
Create model Post in app directory like app/Post.php like below.
<?php namespace App;
use Illuminate\Database\Eloquent\Model;
class Post extends Model {
protected $table= ‘posts’;
protected $fillable = ['title','body'];
}
You can also generate an Eloquent model using make:model artisan command.
By convention, the names of the model are written in the singular form; a model named Post will map to the table posts automatically. But yes you can explicitly tell Laravel Eloquent to which table to use, by setting the protected $table
property, as we done here in the above example of Post model.
Now here’s something to note- Eloquent will assume that each table has a primary key column named id. If you want to define something different, then you can, by setting the primaryKey property.
Querying
Retrieving all the records from database
$posts = Post::all();
Retrieving a record by Primary Key
$post = Post::find(1);
var_dump($post->title);
// find the record or throw an exception if not found
$post = Post::findOrFail(1);
And to query aggregates:
$posts = Post::where('views', '>', 150)->count();
Mass assignment
When you create a new model by passing the array of attributes to the model then these attributes are assigned to model via mass-assignment. There can be a security concern, imagine what can happen when the user is free to modify all the attributes of the model; Well that’s a problem. But hey we are talking about Laravel’s Eloquent, so here’s a solution for this, the fillable and guarded properties of the eloquent model.
The fillable property specifies which attributes should be mass-assignable.
And guarded is just inverse of fillable.
class User extends Model
{
protected $fillable = ['name', 'email'];
protected $guarded = ['id', 'password'];
}
Insert, Update, Delete
Insert
To create a new record in the database form a model, you just have created a new model instance and call the save()
method in it.
$post = new Post;
$post->title = ‘Amazing Laravel’;
$post->body = ‘Laravel is an awesome PHP framework’;
$post->save();
And that’s it. Isn’t that’s cool!
Model create method
// Create a new post in the database...
$post = Post::create(['title' => 'new post']);
// Retrieve the user by the attributes, or create it if it doesn't exist
$user = User::firstOrCreate(['name' => 'Foo']);
// Retrieve the user by the attributes, or instantiate a new instance
$user = User::firstOrNew(['name' => 'Bar']);
Update
$post = Post::find(1); // finding the post for update
$user->email = 'user1@users.com';
$user->save(); // saving the record
Delete
Soft Deleting
Soft deletes allows creating a trash or bin functionality. When we soft delete a model, the record is not actually removed from the database but instead a deleted_at
attribute is set on the model with the timestamp.
So here’s how we enable SoftDeletes in a Model
<?php namespace App;
use Illuminate\Database\Eloquent\Model;
// import SoftDeletes trait
use Illuminate\Database\Eloquent\SoftDeletes;
class Post extends Model {
// using the SoftDeletes trait
use SoftDeletes;
protected $table = ‘posts’;
// telling Laravel to also treat
// ‘deleted_at’ attribute as a Carbon instance
protected $dates = [‘deleted_at’];
protected $fillable = ['title','body'];
}
While creating the migration, add deleted_at column to your table by using the softDeletes method:
$table->softDeletes();
So if you wish to perform a delete then use this:
Post::destroy(1);
Then if the softDeletes are being used then the deleted_at
column will get updated a while querying or retrieving data using eloquent model, then those records will not appear in the results
So what if you want those deleted models to appear in the results? Well, then you have to use withTrashed()
method.
$posts = Post::withTrashed()->find(5);
You may also use the withTrashed()
method on defined relationships.
$user->posts()->withTrashed()->get();
And in case you want only deleted models in your results, then you may use onlyTrashed()
method.
$posts = Post::onlyTrashed()->find(5);
$user->posts()->onlyTrashed()->get();
To check if a model has been soft deleted you will use trashed()
method
if($post->trashed())
{
//
}
So what about restoring the deleted models; well that also pretty easy with restore()
method. Take a look.
$post->restore();
Post::onlyTrashed()->find(5)->restore();
$user->posts()->restore();
If you like to literally delete the record from the database, then you have to use forceDelete()
method.
$post->forceDelete();
Post::onlyTrashed()->find(5)-> forceDelete();
$user->posts()->forceDelete();
Accessors and Mutators
There is a great way to transform an attribute while getting or setting it in Laravel.
Accessors
An Accessor is a getter method of an attribute on your model so that while getting the attribute value, you can gracefully transform its value while retrieving.
To create an accessor, you have to define it in camel-case like getTitleAttribute method even if the attribute is in snake-case on your database.
<?php namespace App;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class Post extends Model {
use SoftDeletes;
protected $table = ‘posts’;
protected $dates = [‘deleted_at’];
protected $fillable = ['title','body'];
// post title accessor
public function getTitleAttribute($value)
{
return ucfirst($value);
}
}
Mutators
Mutators are the setter methods that can be used to set the value of an attribute while we are creating, inserting or updating the model.
<?php namespace App;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class Post extends Model {
use SoftDeletes;
protected $table = ‘posts’;
protected $dates = [‘deleted_at’];
protected $fillable = ['title','body'];
// post title accessor
public function setTitleAttribute($value)
{
$this->attributes[‘title’] = strtolower($value);
}
}
Query Scopes
Scopes are re-usable logical queries in models. Query scopes are very easy to create and use.
Let’s see how to define a query scope.
<?php namespace App;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class Post extends Model {
use SoftDeletes;
protected $table = ‘posts’;
protected $dates = [‘deleted_at’];
protected $fillable = ['title','body'];
// published scope
public function scopePublished($query)
{
return $query->where(‘published_at’,’<=’,Carbon::now());
}
// popular scope
public function scopePopular($query)
{
return $query->where(‘views’,’>’,150);
}
}
And the usage will be like:
$posts = Post::published()->popular()->get();
Now that looks quite simple and easy to use.
For further reference on Laravel Eloquent you can visit Laravel Documentation