November 1, 2024
If you work with Laravel, you probably work with Eloquent. But have you ever wondered what Eloquent actually is? Other than retrieving and manipulating data saved in a database?
You might even know that Eloquent implements the Active Record pattern. But if you are anything like me, you might wonder what the Active Record pattern is and what the alternatives are.
Here is a short overview:
The Active Record pattern is an architectural pattern used to access data in a database. The database table (or view) is wrapped into a class (User::class()
). Every row in the table is an instance of that class, so every time a new class instance is created, a row is created; every time an instance is deleted, a row is deleted.
Active record is an ORM - Object Relational mapper. This layer sits between the database and the application. It connects the application to the database using Object Oriented principles, which means you can write object-oriented code throughout the application.
An alternative to Active Record is the Data Mapper. The difference between Data Mapper and Active record is that Data Mapper completely separates the domain from the application's persistence layer (database). It is the middle layer, a buffer that filters and modifies retrieved data before reaching the resource. That means that the resource model knows nothing about the database. We can have a User
entity (resource) and then create UserMapper
class to map this entity to a table. UserMapper
is a plain PHP class where we write the raw SQL code to communicate with the database, validate data, etc. We have to write it all manually; it does not know any methods you might be familiar with from Eloquent, such as save()
, delete()
. A popular PHP data mapper is Doctrine.
Now that we know what Eloquent is, what Active Record is, and what the alternative to Active Record is, we can move on.
In Laravel, we use Eloquent, but we can also use the query builder. So what is the difference between these two, and when do you use them?
Eloquent is good because it has simple object-oriented syntax, you don't need to know SQL very well to use it, the code is more readable and maintainable, it does a lot of extra things (eager/lazy loading), validations, and it's great when working with relationships between tables. It also helps protect against SQL injections - but be careful; bad code can still be susceptible to this vulnerability. However, it is slower than a query builder, so it should be used on a limited amount of data. That's because it has to make unoptimised queries. After all, it doesn't know your specific use case to make them more optimised.
When there is a lot of data or a lot of complicated joins, it's better to use the Laravel query builder and the DB facade. Not only does the query builder protect against SQL injections, it's also much faster than Eloquent. However, the downside is that it is not as easy to write because you need to write raw SQL; the code might be uglier and harder to maintain.
The good news is that you can use both in a project, depending on what kind of data you are working with.
Let's look at an example of retrieving a user with the ID of 14 but only selecting a couple of columns from the table - the id
, the name
, the email
, and the phone_number
.
Raw SQL query would look like this:
SELECT id, name, email, phone_number FROM users WHERE id = 14
The Eloquent query might look like this (there are various ways to do this in Eloquent, this is just one way):
User::select('id', 'name', 'email', 'country', 'phone_number')->find(14);
And the query builder query might look like this:
DB::table('users')->where('id', 14)
->select('id', 'name', 'email', 'country', 'phone_number')
->get();
So there you have it. Knowing the difference between these approaches means you can choose the one that is the best for your specific use case.