Laravel Eloquent Cheatsheet - everything you need to know

Laravel Eloquent Cheatsheet

Table of contents for this Cheat sheet: How to order a Laravel hasMany relationship?A list of operators on Eloquent's where() methodHow to provide a default model object for relationships?How to prevent Eloquent from adding created_at or updated_at timestamps?How to undelete a soft deleted Eloquent row?How to eager load multiple levels of relationships in Eloquent?How to generate an array for a dropdown (with ['key' => 'value']) suitable for a dropdown, from a Laravel collection of Eloquent objects?How to get table column names from a database table in Eloquent?How to check if a relation was loaded on an Eloquent model already?How to get the first row that matches some where queries, or create it if it doesn't exist (in Laravel's Eloquent)?How to find an item by Primary Key in Eloquent, or throw a ModelNotFoundException exception if it isn't found?How to return an item in Eloquent, or throw a ModelNotFoundException exception if it isn't found?How to select all rows for a certain month (or day, year or time), using Eloquent

How to order a Laravel hasMany relationship?

You can simply add a ->orderBy() to the hasMany relationship

  1. return $this->hasMany(Post::class)->orderBy('updated_at');
View More Details (and 5 discussions about this topic) Here...

A list of operators on Eloquent's where() method

When you use Eloquent's where() method, by default it will use the = operator (i.e. ->where('fieldname','value') will generate ... WHERE `fieldname` = 'value'....

However you are not limited to just =. You can do something like this:

  1. $posts = Post::where("id","!=",123)->get()

Any of the following may be used as the second parameter (and use the third param for the value)

=, <, >, <=, >=, <>, !=, LIKE, NOT LIKE, BETWEEN, ILIKE

(ILIKE = case insensitive like, I believe this is just for Postgre)

View More Details (and 8 discussions about this topic) Here...

How to provide a default model object for relationships?

If you have a relationship (such as a belongsTo()) relationship, it might not always return a result.

This will then mean that every time you do something like this:

  1. $post = Post::first();
  2. $author = $post->author; // what if the relationship in author() returns nothing?
  3. echo $author->name; // $author might have been null, so this will cause an error

There are three main options to handling this:

1) wrap everything in optional() (which will let you do anything to that variable and it will return null if there was nothing set).

2) Wrap everything in if ($author) { ... } to make sure $author isn't a null value

3) or set a default model. If nothing is found for a relationship then it will create an empty object (of the same type as the relationship defines - in the case below it will be \App\User).

  1. /**
  2.  * Get the author of the post.
  3.  */
  4. public function user()
  5. {
  6.     return $this->belongsTo('App\User')->withDefault();
  7. }
  8.  
  9. // you can also define some defaults for the default!
  10.  
  11. /**
  12.  * Get the author of the post.
  13.  */
  14. public function user()
  15. {
  16.     return $this->belongsTo('App\User')->withDefault([
  17.         'name' => 'Guest Author',
  18.     ]);
  19. }
  20.  
  21. /**
  22.  * Get the author of the post.
  23.  */
  24. public function user()
  25. {
  26.     return $this->belongsTo('App\User')->withDefault(function ($user) {
  27.         $user->name = 'Guest Author';
  28.     });
  29. }
View More Details (and 3 discussions about this topic) Here...

How to prevent Eloquent from adding created_at or updated_at timestamps?

If you want to disable both created_at and updated_at then add this to your model:

  1. const UPDATED_AT = null;
  2. const CREATED_AT = null;

If you want to disable just one of those fields (i.e. turn off created_at but keep updated_at, or keep created_at but disable the updated_at field) then just add the one line as required.

Also remember to remove this from the migrations:

  1. $table->timestamps()

Note: There is also the DELETED_AT const, if you use SoftDeletes.

View More Details (and 5 discussions about this topic) Here...

How to undelete a soft deleted Eloquent row?

Use the restore() method.

  1. User::withTrashed()->where("id",1)->restore()
View More Details (and 7 discussions about this topic) Here...

How to eager load multiple levels of relationships in Eloquent?

You can use the 'dot notation' to eager load multiple levels of relationships in Eloquent

  1. $posts = Posts::with("comments.author")->get();

This will load the comments relationship, and load the authors for each comment. Of course this assumes that you have set up the relationships correctly in your models

View More Details (and 10 discussions about this topic) Here...

How to generate an array for a dropdown (with ['key' => 'value']) suitable for a dropdown, from a Laravel collection of Eloquent objects?

The answer used to be list(), but now the answer is pluck()

  1. $posts = Post::all();
  2.  
  3.         echo Form::select("post_id", $posts->pluck("title","id"));
  4.  
  5.         // $posts->pluck("title","id") will produce something like this:
  6.         // [
  7.         //   1 => "post title 1",
  8.         //   5 => "Another post",
  9.         // ...
  10.         // ]

The first param is the actual value you want to 'pluck', and the second value is how you want it keyed. For most cases the second param will be 'id'.

You can also use pluck with just 1 param like this:

  1. $collection = collect([
  2.     ['product_id' => 'prod-100', 'name' => 'Desk'],
  3.     ['product_id' => 'prod-200', 'name' => 'Chair'],
  4. ]);
  5.  
  6. $plucked = $collection->pluck('name');
  7.  
  8. $plucked->all();
  9.  
  10. // ['Desk', 'Chair']

But if more than one item with the same key exists, the last matching one will be used. For example:

  1. $collection = collect([
  2.     ['brand' => 'Tesla',  'color' => 'red'],
  3.     ['brand' => 'Pagani', 'color' => 'white'],
  4.     ['brand' => 'Tesla',  'color' => 'black'],
  5.     ['brand' => 'Pagani', 'color' => 'orange'],
  6. ]);
  7.  
  8. $plucked = $collection->pluck('color', 'brand');
  9.  
  10. $plucked->all();
  11.  
  12. // ['Tesla' => 'black', 'Pagani' => 'orange']

For more details see here.

View More Details (and 5 discussions about this topic) Here...

How to get table column names from a database table in Eloquent?

There are a few methods to get the table column info in Eloquent

  1. \Schema::getColumnListing($this->table)
  1. class User extends Model {
  2.     public function getTableColumns() {
  3.         return $this
  4.             ->getConnection()
  5.             ->getSchemaBuilder()
  6.             ->getColumnListing($this->getTable());
  7.     }
  8. }
View More Details (and 3 discussions about this topic) Here...

How to check if a relation was loaded on an Eloquent model already?

Checking if a relation was loaded (maybe by a with() function call when using the Eloquent query builder) is easy.

From inside your model

If you want to do this within your model, you can use $this->relationLoaded():

  1. // from inside your model:
  2. if ($this->relationLoaded("comments")) {
  3.         //..
  4. }
From outside of your model
  1. $user = User::first();
  2. //
  3. if ($user->relationLoaded("comments")) {
  4.   //
  5. }
View More Details (and 10 discussions about this topic) Here...

How to get the first row that matches some where queries, or create it if it doesn't exist (in Laravel's Eloquent)?

You can use the very useful firstOrCreate() to try and find a row, and create it if it doesn't exist.

  1. // Retrieve flight by name, or create it if it doesn't exist...
  2. $flight = App\Flight::firstOrCreate(['name' => 'Flight 10']);
  3.  
  4. // Retrieve flight by name, or create it with the name and delayed attributes...
  5. $flight = App\Flight::firstOrCreate(
  6.     ['name' => 'Flight 10'], ['delayed' => 1]
  7. );
  8.  
  9. // Retrieve by name, or instantiate...
  10. $flight = App\Flight::firstOrNew(['name' => 'Flight 10']);
  11.  
  12. // Retrieve by name, or instantiate with the name and delayed attributes...
  13. $flight = App\Flight::firstOrNew(
  14.     ['name' => 'Flight 10'], ['delayed' => 1]
  15. );

There is also the firstOrNew which works in the same way, however it will provide an unsaved object (i.e. you will have the model object returned from the method call, but it won't be saved in the DB). There is also the updateOrCreate if you need to update models, or create it if none exist.

View More Details (and 7 discussions about this topic) Here...

How to find an item by Primary Key in Eloquent, or throw a ModelNotFoundException exception if it isn't found?

Use Eloquent's findOrFail($id) method - this will find a model by its primary key or throw an exception.

  1.         $user_id=123;
  2. $user = User::findOrFail($user_id);
  3. // if it cannot find a row with $user_id as the primary key, it will throw a \Illuminate\Database\Eloquent\ModelNotFoundException\ModelNotFoundException exception

If you don't want to throw an exception if none was found then you should just use find() (which will return null if nothing is found.

View More Details (and 10 discussions about this topic) Here...

How to return an item in Eloquent, or throw a ModelNotFoundException exception if it isn't found?

Use Eloquent's firstOrFail(). This is similar to findOrFail(), however findOrFail() does a 'WHERE id = ?' (assuming id is the primary key). With firstOrFail() it will return the first row based on whatever WHERE statements you have.

  1.  $user = User::where("email","[email protected]"->firstOrFail()

If you don't nt to throw an exception if none was found then you should just use first() (which will return null if nothing is found.

View More Details (and 9 discussions about this topic) Here...

How to select all rows for a certain month (or day, year or time), using Eloquent

Eloquent makes many things easy, and working with dates is one of them!

There are bunch of built in functions for building a query that work with dates and times:

  • whereDate
  • whereMonth
  • whereDay
  • whereYear
  • whereTime

You can use them like this:

You can use the whereDate() method to compare a column's value against a date:

$users = DB::table('users')
        ->whereDate('created_at', '2019-11-31')
        ->get();

The whereMonth() method can be used for comparing a column's value against a specific month of a year:

$users = DB::table('users')
        ->whereMonth('created_at', '10')
        ->get();

The whereDay() method may be used to compare a column's value against a specific day of a month:

$users = DB::table('users')
        ->whereDay('created_at', '20')
        ->get();

The whereYear() method may be used to compare a column's value against a specific year:

$users = DB::table('users')
        ->whereYear('created_at', '2019')
        ->get();

The whereTime() method may be used to compare a column's value against a specific time:

$users = DB::table('users')
        ->whereTime('created_at', '=', '11:20:45')
        ->get();
View More Details (and 8 discussions about this topic) Here...