Make CallBack in Having

3

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

$q = Model::where(function($query){
   $query->where(...);
});
I would like to do something like this, but with having () , since I need to check if a given variable exists to do having () .
$q = Model::having(function($query){
   if($var)
       $query->having(...);
});

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

    
asked by anonymous 24.05.2016 / 16:07

2 answers

3

In Laravel, some query methods do not accept callbacks .

It seems to me that you are trying to use the same functionality as whereSub , where you pass Closure as an argument, so you can if in.

Although you can do this, the purpose of where with callback is not to do ifs, but to include the where clause with parenthesis.

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

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

Then you ask the query like this:

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

Some developers often do it differently. They often "break up" the query, since Laravel uses the Fluent Interface pattern. So you can "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);

Update

There are some things in Laravel that you will only find out if you have the habit of futuring the source code, as I usually do.

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

I just discovered that there is a method called when within 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;
}

Class link in GITHUB

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

It's as simple as this:

  $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 from $idade to 17 . Everything that is set in callback of when will be ignored.

    
24.05.2016 / 16:13
4

Builder does not have callback for the having method. As there is a doubt of generating a specific SQL, it would be cool to put your example SQL query in, because having can cause significant differences in your result.

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

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

When calling your Eloquent Builder do:

Model::wherehaving($value)

and continue to do the code.

That way it's clearer and you do not get too big a 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

    
24.05.2016 / 17:05