4

I would like to make a function that can return a Query\Builder that will always return an empty set.

I am making some helper functions and Query\Builder objects get passed around. In certain situations, I always want the result Query\Builder object to return an empty set, regardless of what gets added later.

An example is below. I have a function that returns a query get_users_for_wednesdays, and the result gets passed to another function that adds on a where clause. I don't what to have to check for the existance of a query in filter_for_steves, I just want to modify it and return a query.

Is there an efficient query that always produces an empty set? Ideally one that short-circuits before actually querying the database.

public function get_users_for_wednesdays()
{
   if (is_wednesday())
   {
       return \App\User::query();
   }
   else
   {
       // HOW TO RETURN QUERY FOR EMPTY RESULT SET HERE?
   }
}

public function filter_for_steves($users)
{
    return $users->where('name', 'steve');
}

public getThirdWednesdayStevesAttribute()
{
    $users = get_users_for_wednesday();

    return filter_for_steves($users)->get();
}
Josh Petitt
  • 9,371
  • 12
  • 56
  • 104
  • This might be what you are looking for: http://stackoverflow.com/questions/23599584/how-to-manually-create-a-new-empty-eloquent-collection-in-laravel-4 – whitwhoa Apr 03 '17 at 19:49
  • @commanderZiltoid, thanks! I was reading your original answer, and then it was suddenly gone :-) I don't know if the link you posted is what I want since that seems to be dealing with a Collection? I want the Query\Builder to be able to be modified, but always return an empty set when `get()` is called. – Josh Petitt Apr 03 '17 at 19:53
  • 3
    `return \App\User::query()->limit(0);` but you must be careful with it. – skido Apr 03 '17 at 20:02
  • @skido, thanks that looks pretty good. May I ask why you specifically suggested I must be careful with it? – Josh Petitt Apr 03 '17 at 20:08
  • @JoshPetitt because it can be changed by paginator. It's much better for you to use scopes. – skido Apr 04 '17 at 06:54

1 Answers1

2

Your first two functions should be Scopes.

It makes more sense to put the is_wednesday() check in the function that's building the query, but if you prefer the other way scopeUsersForWednesday() can just return the $query without modifying it when is_wednesday() returns false.

public function scopeUsersForWednesday($query)
{
    // Replace with whatever your actual query should be
    return $query;
}

public function scopeFilterForSteves($query)
{
    return $query->where('name', 'steve');
}

public function getThirdWednesdayStevesAttribute()
{
    $query = User::filterForSteves();

    if (is_wednesday()) {
        $query = $query->usersForWednesday();
    }

    return $query->get();
}
Ethan H.
  • 116
  • 5
  • I was looking at scopes just now, this seems promising, I will investigate more. – Josh Petitt Apr 03 '17 at 20:09
  • I'm going to mark this as correct because after more reading, it does seem like "the right way to do it". I'll re-evaluate if more answers are posted. Thanks! – Josh Petitt Apr 03 '17 at 20:13