Laravel Eloquent ORM

Apr 5, 2016, Tags - Laravel

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


Tags - Laravel

Abid Raza

Editor

Leave a comment