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. Eloquent ORM looks like a simple mechanism, but under the hood, there’s a lot of semi-hidden functions and less-known ways to achieve more with it. In this article, I will show you a few tricks.
Increments and Decrements
Instead of doing this way:
$post= Post::find($post_id);
$post->read_count++;
$post->save();
Do this:
$post= Post::find($post_id);
$post->increment('read_count');
$post->save();
You can also write it as follows:
Post::find($post_id)->increment('read_count');
Post::find($post_id)->increment('read_count', 10);
Product::find($product_id)->decrement('stock');
The Exists Property
The exists property is utilized to show whether the object exists in the database or not. When you create a new model instance the exists property will be set to false. Once your model is saved or retrieved from the database the exists property will be set to true.
$product = new Product();
$product->title = 'xyz';
$product->category= 'electronics';
$product->exists; //false
$product->save();
$product->exists; //true
The push() Method
The push() method saves the model and all of its relationships.
$product = Product::where('title', 'xyz')->first();
$product->price= '100';
$product->store->name= 'Lorem ipsum';
If you call the save method then only the product’s price will be saved and not the store name. For that to happen, you should call the push method. Because the push method saves the original model and all of its relationships.
//Only saves the original model
$product->save();
//Also saves the relationship related to original model
$product->push();
Examining Attribute Changes
Eloquent provides the isDirty, isClean, and wasChanged methods to examine the internal state of your model and determine how its attributes have changed from when the model was originally retrieved.
The isDirty method determines if any of the model’s attributes have been changed since the model was retrieved. You may pass a specific attribute name to the isDirty method to determine if a particular attribute is dirty. The isClean will determine if an attribute has remained unchanged since the model was retrieved. This method also accepts an optional attribute argument:
use App\Models\User;
$user = User::create([
'first_name' => 'Adam',
'last_name' => 'Smith',
'title' => 'Developer',
]);
$user->title = 'Designer';
$user->isDirty(); // true
$user->isDirty('title'); // true
$user->isDirty('first_name'); // false
$user->isClean(); // false
$user->isClean('title'); // false
$user->isClean('first_name'); // true
$user->save();
$user->isDirty(); // false
$user->isClean(); // true
The wasChanged method determines if any attributes were changed when the model was last saved within the current request cycle. If needed, you may pass an attribute name to see if a particular attribute was changed:
$user = User::create([
'first_name' => 'Adam',
'last_name' => 'Smith',
'title' => 'Developer',
]);
$user->title = 'Designer';
$user->save();
$user->wasChanged(); // true
$user->wasChanged('title'); // true
$user->wasChanged('first_name'); // false
Find Multiple Entries
The find() method is quite common, but you would be pretty astonished how few people know that it can accept multiple IDs as an array:
For example:
$product = Product::find([1,2,3]);
findOrFail() Method
The findOrFail method will retrieve the first result of the query; however, if no result is found, an Illuminate\Database\Eloquent\ModelNotFoundException will be thrown:
So Instead of doing this:
$product = Product::find($id);
if (!$product) {
abort (404);
}
Do this:
$product = Product::findOrFail($id);
firstOrCreate() Method
The firstOrCreate method will attempt to locate a database record using the given column/value pairs. If the model can not be found in the database, a record will be inserted with the attributes resulting from merging the first array argument with the optional second array argument:
So instead of doing this:
$user = User::where('email', 'jhon@gmail.com')->first();
if (!$user) {
User::create(['email' => 'jhon@gmail.com'
]);
}
Do this:
$user = User::firstOrCreate([ 'email' => 'jhon@gmail.com' ]);
Chunk() Method for Big Datasets
The chunk method breaks the collection into multiple, smaller collections of a given size:
$collection = collect([1, 2, 3, 4, 5, 6, 7]);
$chunks = $collection->chunk(4);
$chunks->all();
When working with big datasets instead of getting all the records for some table you can get a certain amount with the chunk() method like this:
$users = User::all();
foreach($users as $user){
//
User::chunk(50, function ($users){
foreach($users as $user){
//...
}
});
Use hasMany() to Create Many
If you have a hasMany() relationship, you can use saveMany() to save multiple “child” entries from your “parent” object, all in one sentence:
$post= Post::find(1);
$post->comments()->saveMany([
new Comment([ 'message' => 'My First Comment' ]),
new Comment([ 'message' => 'My Second Comment' ]),
]);
Closing Notes
Eloquent has many excellent functionalities, that I explained above. I hope you will find them helpful and implement them in your Laravel Projects.