6 Laravel Eloquent Secrets to improve your code

Published on by

6 Laravel Eloquent Secrets to improve your code image

Eloquent is the default ORM that ships with Laravel. It implements the Active-Record pattern and provides an easy way to interact with your database. Every single model represents a table in your database with which you can work. In this post, we’ll show you more or less hidden secrets, methods, and properties you might not know to improve your code.

Snake Attributes

Snake Attributes are an interesting one. Let’s take a look at what the code says:

* Indicates whether attributes are snake cased on arrays.
* @var bool
public static $snakeAttributes = true;

Very often, people make a mistake to use this property to change the way how to access properties. Many people believe that if they change this property, they can easily access the attributes using camel-case annotation. That’s not the case. We strongly advise against using it. It is merely there to define whether attributes are camel or snake-cased when the model is output as an array.

If you want to work camel-case based, we recommend you take a look at the package Eloquence by Kirk Bushell.


If you use Laravel’s Eloquent ORM, you’re in luck. It provides an easy way to paginate results out of the box. You might be familiar with something like this:

$comments = Comment::paginate(20);

With this method, you can paginate the comment model with 20 items per page. Changing that value gives you the possibility to define how many items are displayed per page. If you do not specify anything, the default gets applied, which is 15.

Assume that you want to display comments in several places on your website. Always 30 comments per page. Then it would be bothersome if you have to pass the parameter 30 at every place. Therefore you can set a new default value directly on the model.

protected $perPage = 30;

Appending custom values to models

Eloquent has a great feature called “Accessors”. The feature allows you to add custom fields to models that don’t exist on the model or in the table. It doesn’t matter if you use existing values or define completely new ones. You can return anything. Here is an example of how Accessors work. Given there is a model called User where we put the code below.

function getFullNameAttribute() {
return sprintf('%s %s', $this->first_name, $this->last_name);

Now you have access to a full_name attribute on the post model, like this:


The problem is now if you return objects, like a collection, this attribute doesn’t get appended to the user model. Add the protected $appends attribute to your model. It accepts an array with one or multiple fields that should automatically be appended from now. This is how it looks like:

protected $appends = ['full_name'];

Mutators for non-existing columns

Mutators are the opposite of Accessors. You can use them for really cool stuff. For example, to convert different inputs. Let’s show you something. Imagine you want to save a kind of time period. Usually, you always save the smallest possible unit. In our case seconds. For UX reasons, the user doesn’t want to enter seconds, but for example, minutes in one place, or hours in another place. It can all be solved very quickly.

class Video extends Model
public function setDurationInMinutesAttribute($value)
$this->attributes['duration_in_seconds'] = $value * 60;
public function setDurationInHoursAttribute($value)
$this->attributes['duration_in_seconds'] = $value * 60 * 60;

What does it mean? It means that you can use the non-existent column duration_in_minutes on the model, but in the background, the column duration_in_seconds is updated. The same applies to the non-existent column duration_in_hours. This results in the following logic, for example:

class AnyController
public function store()
'title' => request('title'),
'duration_in_minutes' => request('duration_in_minutes'),

This saves you the calculation in the controller, and you can simply use a non-existent column and use a mutator to map it correctly to the correct column while performing some calculations.

Eager loading with $with

Let’s talk a little about relations. By default, Laravel uses lazy loading. What does that mean in terms of relations? The good thing is that lazy loading saves memory because not all data has to be kept, and we load the data when we need it. Consider this code sample:

$comments = Comment::all();
foreach ($comments as $comment) {
echo $comment->user->name;

In the example above, we get all comments. Then we loop through the comments and display the username for each comment. The code works, but we run into a problem. Lazy loading now makes sure that the query to get the user is only executed when we want to output the username.

Welcome to your first N+1 problem. Why N+1? N is always the number of comments, and 1 is the query to get the comments at all. For example, if we have 500 comments, then the query to get all comments is fired once and then one query to get the corresponding user – per comment. So 500 + 1 queries. This means that as the number of comments increases, the number of queries increases as well.

To prevent it there is something called eager loading.

$comments = Comment::with('user')->get();
foreach ($comments as $comment) {
echo $comment->user->name;

That ends in two queries. The first query fetches all comments, and the second query immediately fetches all associated users. In the background, the following happens (simplified):

SELECT id, user_id, body FROM comments;
SELECT name FROM users WHERE user_id IN (1,2,3,4,5...);

Whether 10, 500 or 10000 comments are fetched at the end is not essential. Two queries remain.

You have now seen how you can use eager loading. But only how to use it manually. You can also automate the whole thing so that certain relations are always loaded automatically by eager loading. For this there is a property on the model.

protected $with = [];

So we can simply set the property protected $with = ['user']; on our Comment model, and from now, the user is automatically loaded at any time.

There are many more possibilities with eager loading. Loading of specific columns only, nested eager loading, multiple eager loadings, and much more. Head over to the Laravel documentation or deep dive into the core.

Model keys

From time to time, there is the need to fetch all IDs of a specific query. It does not matter whether this is a complex query or not. Most people would probably do the following:


This works great. But now you get a collection back. To get an array, you would have to pass it to the toArray() method again.


In most cases, however, this can be shortened. Like this:


This method returns an array. In our case, the IDs. It is important to understand that this method does not always necessarily return IDs. It returns, as the name says, all primary keys as an array. The primary keys can be defined in the model. The default is id.

protected $primaryKey = 'id';
Stefan Bauer photo

Creator of PingPing.io ・ Author of Laravel Secret ・ Full Stack developer and a huge fanboy of Laravel, InertiaJS, Livewire and TailwindCSS.

Filed in:

Laravel Newsletter

Join 40k+ other developers and never miss out on new tips, tutorials, and more.


Version 4 of Tinkerwell is available now. Get the most popular PHP scratchpad with all its new features and simplify your development workflow today.

Visit Tinkerwell
Laravel Forge logo

Laravel Forge

Easily create and manage your servers and deploy your Laravel applications in seconds.

Laravel Forge
Tinkerwell logo


The must-have code runner for Laravel developers. Tinker with AI, autocompletion and instant feedback on local and production environments.

No Compromises logo

No Compromises

Joel and Aaron, the two seasoned devs from the No Compromises podcast, are now available to hire for your Laravel project. ⬧ Flat rate of $7500/mo. ⬧ No lengthy sales process. ⬧ No contracts. ⬧ 100% money back guarantee.

No Compromises
Kirschbaum logo


Providing innovation and stability to ensure your web application succeeds.

Shift logo


Running an old Laravel version? Instant, automated Laravel upgrades and code modernization to keep your applications fresh.

Bacancy logo


Supercharge your project with a seasoned Laravel developer with 4-6 years of experience for just $2500/month. Get 160 hours of dedicated expertise & a risk-free 15-day trial. Schedule a call now!

Lucky Media logo

Lucky Media

Bespoke software solutions built for your business. We ♥ Laravel

Lucky Media
Lunar: Laravel E-Commerce logo

Lunar: Laravel E-Commerce

E-Commerce for Laravel. An open-source package that brings the power of modern headless e-commerce functionality to Laravel.

Lunar: Laravel E-Commerce
LaraJobs logo


The official Laravel job board

Larafast: Laravel SaaS Starter Kit logo

Larafast: Laravel SaaS Starter Kit

Larafast is a Laravel SaaS Starter Kit with ready-to-go features for Payments, Auth, Admin, Blog, SEO, and beautiful themes. Available with Vue and Livewire stacks.

Larafast: Laravel SaaS Starter Kit
SaaSykit: Laravel SaaS Starter Kit logo

SaaSykit: Laravel SaaS Starter Kit

SaaSykit is a Laravel SaaS Starter Kit that comes with all features required to run a modern SaaS. Payments, Beautiful Checkout, Admin Panel, User dashboard, Auth, Ready Components, Stats, Blog, Docs and more.

SaaSykit: Laravel SaaS Starter Kit
Rector logo


Your partner for seamless Laravel upgrades, cutting costs, and accelerating innovation for successful companies


The latest

View all →
Asserting a JSON Response Structure in Laravel image

Asserting a JSON Response Structure in Laravel

Read article
Backpack turns 8 years old, celebrates with 40% discount image

Backpack turns 8 years old, celebrates with 40% discount

Read article
Create a DateTime from a Timestamp With this New Method Coming to PHP 8.4 image

Create a DateTime from a Timestamp With this New Method Coming to PHP 8.4

Read article
Neovim Plugin to for Navigating Laravel and Livewire Components image

Neovim Plugin to for Navigating Laravel and Livewire Components

Read article
Laravel Herd v1.7 is out with updates to the dump UI image

Laravel Herd v1.7 is out with updates to the dump UI

Read article
Share Error Package for Laravel's New Exception Page image

Share Error Package for Laravel's New Exception Page

Read article