Jozsef Hocza

Eloquent Abused By Many Developers

Slow Code series

Note: I dropped the clickbait Title prefix (Why Laravel Is Slow) for my Slow Code Series. :)

Today we will look at one of the most failed task: JOIN with Eloquent. Hit up a random Laravel open source project and surely you will find something like this.

<?php

$category = Category::findOrFail($id);
$posts = $category->posts()->whereStatus(1)->get();
foreach($posts as $post) {
	/* code */
}

“But hey dude, it is just OK…”

Well, in this special case, it is!

However, Let’s push it a little bit. How about this one?

<?php

$categories = Category::all(); // Let's say we have 40 categories
foreach($categories as $category) {
    $posts = $category->posts()->whereStatus(1)->get();
    foreach($posts as $post) {
        /* code */
    }
}

Here we are, making 41 times more SQL queries instead of 2.

So what is the correct approach here?

<?php 

$categories = Category::with(['posts' => function ($q) {
   $q->whereStatus(1);
}])->get();

foreach($categories as $category) {
    foreach($category->posts as $post) {
        /* code */
    }
}

My note on Eloquent abusement

I found a secret fact behind all these actions. Some developer look at Eloquent as a “magical object” that will optimize and does everything by the book in the background and you are not working with SQL anymore. Please do not assume that. You will be always getting SQL at the end, no matter what. If you mess up, if you call Eloquent too many times you are creating and sending that many queries to the database.

Post::find(1);
SELECT * FROM posts WHERE id=1

Some people think after you used Post::find(1): “It is in the memory. If I use this line of code again, not going to touch the database.” They could not be more wrong.

Hunting down abusive code

If you are up for the task, I found Barry’s package the most useful in this fight: laravel-debugbar

So, try to kill all those bitchy lines of code in your projects, and try to cache as much as possible.

The Goal is: Zero query when you refresh the page.

Try to reach this goal. It is vital for your application.

Eloquent Hotline

Stand up and say NO!

Please if you witness an abusive action against Eloquent make sure to send this post’s url to that person. He might find useful the other posts from the Slow Code Series. :)

Oh, and do not forget to subscribe!


Share this:

SUBSCRIBE
Subscribe to my e-mail list.
You can unsubscribe anytime.