Introduction
I recently put out a poll on Twitter asking which variation of code Laravel developers prefer to use. The piece of code was only a little snippet, but it seemed to get quite a bit of attention with a lot of opinions on either option.
So, I thought I'd put together a Quickfire blog post to quickly look over the code snippet in the poll, the results, and the different opinions that I saw mentioned in the comments.
The Tweet
So, let's first look at the tweet:
Which approach do you prefer to use in your Laravel Eloquent queries? ๐ค
— Ash Allen ๐ (@AshAllenDesign) February 25, 2022
I think I prefer option 1 personally#laravel #php pic.twitter.com/QMhDIHoDJg
The poll was asking which approach developers prefered when using Laravel Eloquent queries:
1// Option 12User::where('email', $email)->get();3 4// Or, option 25User::query()->where('email', $email)->get();
By the time the poll had finished, it had received 864 votes.
66.4% voted for option 1 (not using ::query()
).
The remaining 33.6% voted for option 2 (using ::query()
).
The Code
One question that I saw several times was "what's the difference between the two?". That's a very valid question and when I first saw some code a few years ago using ::query()
, I wondered the same thing.
So, to keep it short, the answer is that there isn't really a difference in the outcome. To understand this, let's take a look at this code snippet:
1User::where('email', $email)->get();
A where
method doesn't actually exist on the User
class or the Model
class that it extends. Therefore, the __call
magic method (shown below) is called on the Model
class when we try to call where
. As a result of this, the bottom line (line 18) is then called which creates a new \Illuminate\Database\Eloquent\Builder
which does include the where
method.
/Illuminate/Database/Eloquent/Model.php
1/**2 * Handle dynamic method calls into the model.3 *4 * @param string $method5 * @param array $parameters6 * @return mixed7 */8public function __call($method, $parameters)9{10 if (in_array($method, ['increment', 'decrement'])) {11 return $this->$method(...$parameters);12 }1314 if ($resolver = (static::$relationResolvers[get_class($this)][$method] ?? null)) {15 return $resolver($this);16 }1718 return $this->forwardCallTo($this->newQuery(), $method, $parameters);19}
To explain this in a simpler way, whenever we call a query method (such as where
) on a model, it will automatically create the Builder
object and append the where
clause that we would have had to create manually ourselves using User::query()->where()
. So, they both achieve the same things.
Reasons for Using query()
Improved Visuals
A few developers mentioned that they liked to use query()
method in queries that had conditional statments (such as if
or when()
). For example, let's take this query:
1$query = User::where('email', $email);2 3if ($approvedOnly) {4 $query->where('is_approved', true);5}6 7$result = $query->get();
It could also be written as:
1$result User::where('email', $email)2 ->when($approvedOnly, function ($query) {3 $query->where('is_approved', true);4 })5 ->get();
But, by using the query()
model at the start of the query, the code might look like this instead:
1$result User::query()2 ->where('email', $email)3 ->when($approvedOnly, function ($query) {4 $query->where('is_approved', true);5 })6 ->get();
As a few people mentioned in the Twitter comments, by doing this, it pushes all of the query constraints on to a new line and they all vertically align in the code. So, although it doesn't necessarily affect the code itself, it can appear a little bit easier to read for some developers. And, to be honest, I agree with this and I think that in these situations, I opt for using the query()
method too.
Better IDE Support
Another pro for using query()
that I saw was improving the IDE support. For example, by adding query()
to the beginning of the queries, it helped the IDE (such as PHPStorm) to understand what the code was being used for. Therefore, it could provide better autocompleting and analysis of your code.
Although this is a very valid point, it's worth noting that this scenario can sometimes be avoided by using the IDE Helper package (barryvdh/laravel-ide-helper). If this isn't something you've come across before, I'd highly recommend checking it out.
Reasons for NOT Using query()
Cleaner, Shorter Code
Some of the comments on the poll mentioned that not using query()
in their code made their code feel cleaner and shorter. They argued that by using things such as where
, with
, whereHas
, and withWhereHas
it made it obvious that the code was in fact a query. So, by adding query()
to it, all it did was add unneeded noise that didn't provide any extra value. This slightly ties in to one of the points from above, where some developer said they only decided to use query()
for more complex queries that contained conditionals.
Should I Use query()?
In my opinion, I'd say that it's purely down to personal preference. I think that using whichever version you think makes you feel most comfortable when building your apps will always be a sensible option.
However, if you're working as part of a team, I think it's important to stick to any standards or style guides if they exist. For example, if your team has a style guide that states that every single query in your application should use the query()
method, then you'll need to remember to stick to that convention. Code that is readable and everyone on your team understands will always be the best option!
Watch on Codecourse
If you're interested in finding out more on this topic, Alex Garrett-Smith put together a really useful course on Codecourse for completely FREE called The Eloquent Query Method.
So, if you prefer to learn through watching videos rather than reading, I'd highly recommend checking it out.
Conclusion
Hopefully, this Quickfire post should have given you a quick insight into why you might want to use query()
or not in your Laravel Eloquent model queries. Which version do you prefer using yourself?
If this post helped you out, I'd love to hear about it. Likewise, if you have any feedback to improve this post, I'd also love to hear that too.
If you're interested in getting updated each time I publish a new post, feel free to sign up for my newsletter below.
Keep on building awesome stuff! ๐