Callback in Having

Asked

Viewed 62 times

3

In Laravel it is possible to make a callback at the time of a consultation. For example:

$q = Model::where(function($query){
   $query->where(...);
});

I’d like to do something similar, but with the having(), since I need to verify if a certain variable exists in order to do the having().

$q = Model::having(function($query){
   if($var)
       $query->having(...);
});

If there is no value in the variable it is not to do the having().

2 answers

4

In the Builder has not callback for the method having. When there is a question of generating a specific SQL, it would be nice to put in your question the SQL example, because, the havingmay cause significant differences in its outcome.

Make a method scopeWherehaving (can be any name, but avoid putting closure and reserved name) for example in this way:

public function scopeWherehaving($query, $value = null)
{
     if (!is_null($value))
     {
         return $query->having('campo', '>', $value);
     }
     return $query;
}

On the call of his Eloquent Builder do:

Model::wherehaving($value)

and continue to code normally.

That way it has more clarity and it doesn’t get a very big code!

In the links below the Framework itself it is easy to see numerous ways to work with Query Builder:

Database: Query Builder

Query Scopes

  • I had already answered that.

  • Although it looks like, I will give a +1, because it is good to worry about the organization of the code :)

  • 1

    Don’t fight, I positive all of you.

3


In Laravel, some consultation methods do not accept callbacks.

It seems to me that you are trying to utilize the same functionality in whereSub, where you pass a Closure as argument and thus you can do the if inside.

Although you can do that, the purpose of where with callback is not making ifs, but encompassing the clause where parenthesely.

In your case, I think you could solve this with the following maneuver: use the Model Scope do Laravel.

 class  Model {
     public function scopeClosure($query, \Closure $callback) {
       $callback($query);
       return $query;
     }
 }

Then you do the consultation like this:

Model::where(['nome' => 'Wallace'])->closure(function ($query) use($var) {
       if ($var) $query->having(...);
});

Some developers usually do it differently. They usually "dismember" the query, since Laravel uses the Fluent Interface standard. Thus, it is possible to "continue" the query you assigned to a variable.

$query = Usuario::orderBy('nome');

// Executa $query se `$var` é verdadeiro
$var && $query->having(...);

$usuarios = $query->where(['nivel_id' => 4])->paginate(15);

Updating

There are some things in Laravel that you will only discover if you have the custom of futucar the source code, as I usually do.

I just saw a feature that was developed designed in cases like yours, highlighted above. But this is a unique solution for those who use Laravel 5.2.

I just found out there’s a method called when within the class Illuminate\Database\Query\Builder.

The code for this method is as follows::

public function when($value, $callback)
{
    $builder = $this;
    if ($value) {
        $builder = call_user_func($callback, $builder);
    }
    return $builder;
}

Link to class on GITHUB

Observing this method, we can understand that it works as follows: You pass a first argument to when. If it is valid, it will execute the query contained within your Closure.

It’s that simple:

  $idade = 26;

  Usuario::where(['nome' => 'Wallace'])->when($idade > 18, function ($query){
           $query->having(....);
    });

In this case above, to test the operation, simply change the value of $idade for 17. Everything defined in callback of when will be ignored.

  • From there inside the Closure function I can put whatever I want inside ? Having, Where... ?

  • I’m going to do a great update now

  • @Peterparker yes, anything works inside that closure. But you better use the example I updated. It’s better

  • Very top indeed. It will help me in the next ones. Your solution helps me, but my query has some particularities difficult to do... and it is not difficult, but Laravel gives me some mistakes that I do not understand why...

  • I am calling WHEN, but it says so: Call to Undefined method Illuminate Database Query Builder::when()

  • It does not have this WHEN function in Laravel 5.1. Tricked me

  • Maybe you only have it in 5.2, I will correct the information. I left the git link

  • So blow it up ?...

Show 3 more comments

Browser other questions tagged

You are not signed in. Login or sign up in order to post.