Inquiry about Laravel and Eloquent

2

I have a form with two select and two date fields, when I click on the button it makes me a query with the value of the two select and "whereBetween" between the dates, is there any way of doing that I only consult according to the select in those who have entered a value?

I have edited the question and added the controller code.

    public function results(Request $request)
{
    $professionals = Professional::where('id', $request->input('professional_id'));
    $resources = Resource::where('id', $request->input('resource_id'));
    $fini = date("Y-m-d", strtotime($request->input('date_start')));
    $ffin = date("Y-m-d", strtotime($request->input('date_end')));
    $coordinations = Coordination::where('professional_id', $request->input('professional_id'))->where('resource_id', $request->input('resource_id'))->whereBetween('date', [$fini, $ffin])->get();

    return view('coordinations.results')->with(compact('coordinations', 'professionals', 'resources'));
}
    
asked by Fernando Torres López 14.02.2018 в 13:18
source

3 answers

2

The other thing you can do is, make a raw query with the method -> whereRaw () and if you are using postgresql as a bd engine, use the COALESCE function in the query (if not you should look for a similar one in the engine of bd that you are using or creating it yourself). Something like this:

->whereRaw('professional_id = COALESCE(?,professional_id)', [$request->input('professional_id')])

and the same with the other where.

What the COALESCE () function does is return the first non-zero variable. For example if the? we replace it with the number to filter, it will do the filtering normally, but if it is null, it will return the second parameter that is the same field therefore it will not filter since that condition is always True.

edit: in MySQL it is in version 5.6 at least.

    
answered by 15.02.2018 в 15:41
1

I recommend you change your function and adapt it to the next one, this example can be useful if you want to search for more than 2 criteria as your selects were

public function results(Request $request)
{
    $professionals = Professional::where('id', $request->input('professional_id'));
    $resources = Resource::where('id', $request->input('resource_id'));
    $fini = date("Y-m-d", strtotime($request->input('date_start')));
    $ffin = date("Y-m-d", strtotime($request->input('date_end')));
    //Si ambos datos no son nulos, ejecuto la consulta tal y como la tenias
    if(isset($professionals, $resources)) {
        $coordinations = Coordination::where('professional_id', $request->input('professional_id'))->where('resource_id', $request->input('resource_id'))->whereBetween('date', [$fini, $ffin])->get();
    } else {
      //Sino asigno los valores a un arreglo apra verificar cual es null y no pasarlo a la consulta
      $campos = [$professionals, $resources];
      //Almaceno las propiedades por las cuales voy hacer los where, como profesional es el primer elemento del arreglo la propiedad es professional_id, y asi sucesivamente
      $propiedad = ['professional_id', 'resource_id'];
      //Recorro el primer arreglo y voy comprobando si tiene valor y está definido
      foreach($campos as $indice => $valor) {
        if(isset($camp)) {
          //Asigno a una variable el queryBuilder de mi consulta para ir anexando las consultas where
          $builder = (isset($builder)) ? $builder->where($propiedad[$indice], $request->input($propiedad[$indice])) : Coordination::where($propiedad[$indice], $request->input($propiedad[$indice]))->whereBetween('date', [$fini, $ffin]);
        }
      }
      //Obtengo el resultado general de la consulta
      $coordinations = $builder->get();
    }

    return view('coordinations.results')->with(compact('coordinations', 'professionals', 'resources'));
}
    
answered by 14.02.2018 в 17:00
0

I propose another option with the code a little cleaner. I hope it helps you, I can not test the code because I do not have your project, but in theory and based on my experience it should work.

public function results(Request $request)
{
    // Inicializo variables
    $professional_id = $request->input('professional_id'); // si no se pasan el valor es null
    $resource_id = $request->input('resource_id'); // si no se pasan el valor es null
    $professionals = null;
    $resources = null;

    $where_array = [];
    // Si se paso valor agrego al array para hacer el where y busco el profesional
    if($professional_id != null) {
        $where_array = array_merge($where_array, ['professional_id' => $professionals->id]);
        $professionals = Professional::find($professional_id);
    }
    // Si se paso valor agrego al array para hacer el where y busco el recurso
    if($resource_id != null) {
        $where_array = array_merge($where_array, ['resource_id' => $resources->id]);
        $resources = Resource::find($resource_id);
    }

    $fini = date("Y-m-d", strtotime($request->input('date_start')));
    $ffin = date("Y-m-d", strtotime($request->input('date_end')));

    $coordinations = Coordination::where($where_array) // solo va a hacer el where de las variables que no este nulas. En caso de no pasar ninguno de los dos devuele todos los registros
                                  ->whereBetween('date', [$fini, $ffin])->get();

    return view('coordinations.results')->with(compact('coordinations', 'professionals', 'resources'));
}
    
answered by 10.03.2018 в 13:00