NoTimeForCaution's avatar

LARAVEL/PHP BEST PRACTICE: IF INSTANCE EXISTS (LOAD TIMES)

What do you folks who make a living at this do for determining if an Instance exists? I know how to do it - I'm interested in how you do it and why?

WHY I CARE?

  1. PRIMARILY, LOADING TIMES
  2. AGAIN, LOADING TIMES - SPECIFICALLY on PAGES RUNNING LARAVEL + VUE
  3. I USE IT VERY OFTEN
  4. I WANT MY CODE TO LOOK LIKE YOURS

I use the below technique in Blade when the view or partial doesn't touch a controller:

@if(App\Model::all()->count() != 0)
    // Vue component which calls laravel endpoint to retrieve data
@else
    // NO DATA
@endif

Is this good practice? I would guess no because I'm not familiar with the behavior. If there are 1000 instances of App\Model are they being counted to satisfy the above or does that stop as soon as it returns a single Model Instance because that's all that's required to return true?

Again, just wondering what you folks to in similar situations to cut down on queries and loading. As my knowledge of Laravel increases I find myself wanting to dig in deeper....

THanks!

0 likes
8 replies
ftiersch's avatar

That's definitely not a good approach since what you're doing is:

Get ALL instances of Model, load them into memory and then count the loaded instances.

I'd recommend either:

Model::count() > 0

or

Model::exists()

Both execute a query against the database but they only get a simple value as a result instead of possibly thousands of rows of data. If you want to have as few queries as possible you could write your own class that executes the query once and then saves the result to a variable.

NoTimeForCaution's avatar

Thanks for the recommendations @ftiersch

Yeah, once I took a look at loading times and queries in Telescope I started to spot some bad conventions. That's what ultimately got me to pose the question in broader terms of how members of the community deal with such things day to day.

I like the idea of custom class generation and hadn't thought of that. In terms of saving to a reusable variable, how is that implemented?

ftiersch's avatar

It could be as simple as this:

class ModelChecker {
    protected static $exists = null;

    public static function modelExists() {
        if (is_null(self::$exists)) {
            self::$exists = Model::exists();
        }

        return self::$exists;
    }
}

But don't over optimize. This doesn't save a lot of time if you only use it in 1 or 2 places. But if you have to check constantly if a model exists it might be worth it.

NoTimeForCaution's avatar

Understood. And thanks for the snippet, I will play around with it.

My main page is an HQ of sorts and grabs instances of all Models (albeit, only a few of them). But it loads in the following fashion:

  1. Single Instance of ModelA
  2. 5 Instances of ModelB
  3. 4 Instances of ModelC
  4. Vue api call to load ModelD

In some cases, there is no data (new or updated) and I just need to return a string to indicate so. That's the basis for my question which led to BEST PRACTICE thought process.

Thanks for chiming in!

EDIT TO ADD:

I was familiar with exists() but after reading Laravel Docs I thought it was used against query constraints and not to determine if a single instance exists.

https://laravel.com/docs/5.8/queries#where-exists-clauses

** Determining If Records Exist **

Instead of using the count method to determine if any records exist that match your query's constraints, you may use the exists and doesntExist methods:

return DB::table('orders')->where('finalized', 1)->exists();

return DB::table('orders')->where('finalized', 1)->doesntExist();
ftiersch's avatar
ftiersch
Best Answer
Level 28

To be honest I haven't tried it in that context either :)

But if it doesn't work you can still use count() > 0

NoTimeForCaution's avatar

To finish up:

@if(Model::exists())

select exists(select * from `model`) as `exists`    0.32ms

My original query

@if(App\Model::all()->count() != 0)
select * from `models`  0.38ms

So, approx 20% slower with a single item in the DB. Huge performance increase with your refactor, @ftiersch

Thanks again!

Please or to participate in this conversation.