TransWikia.com

Consultar un campo con distintos valores

Stack Overflow en español Asked by Soc on December 30, 2021

Que tal soy nuevo en Laravel, he estado intentando realizar un filtro por medio de option multiple:

introducir la descripción de la imagen aquí

Tengo estos Modelos con la Relacion N:M:

Empleado

introducir la descripción de la imagen aquí

Servicio

id | nombre

introducir la descripción de la imagen aquí

empleado_servicios

id | empleado_id | servicio_id

introducir la descripción de la imagen aquí

Cuando intento recuperar los datos con Eloquent:

if(!empty($request->services))
{    

            $services = $request->services;

            $publication_service = Service::whereIn('id',$services)->get();
            
            foreach($publication_service as $publication){

                 $pub[]=$publication->profiles;
            }
            return $pub;
        }

Funciona hasta cierto punto, lo que quiero lograr es que cuando seleccionen las opciones Limpia y Recoge o las tres me envíe solo el empleado que cumpla con esos criterios,en este ejemplo seria el empleado_id = 1, ya que no todos los empleados limpian,recogen ó monitorena, si seleccionan dos de las tres opciones, seria algo como si colocara servicio_id = 1 y servicio_id = 2 lo que actualmente con el wherein no se logra porque me manda los que tienen servicio_id = 1 ó servicio_id = 2, es un OR en ves de AND, y no he logrado concretar esta consulta.

Si se seleccionan los tres criterios sea algo así como :

->where(id,'=',1)
->where(id,'=',2)
->where(id,'=',3)

solo me debería mandar el empleado que tenga los tres servicios activos, no he logrado realizar esta consulta, espero me puedan apoyar saludos.


Muchas gracias Amigo BetaM,

Agradesco tus comentarios, para aclarar lo que recibo en la vista por medio del los option multiple son los id’s de los servicios que actualmente estoy manejando se puede dar de alta n número de servicios para el ejemplo tengo dados de alta por el momento tres servicios:

Tabla del Modelo Servicio

Servicios
id nombre
1  Limpia
2  Recoge
3  Monitorea

<select multiple name="services[]" id="services">
              <option value="" disabled selected>Servicios</option>
              @foreach ($services as $service)
                <option value="{{$service->id}}">{{$service->name}}</option>  
              @endforeach
</select>

En el controlador recibo el Array para realizar la búsqueda:

$services = $request->services;

$publication_service = Service::whereIn('id',$services)->get();
//recorro los datos obtenidos
            foreach($publication_service as $publication){
//Ingreso a la relación con profiles y obtengo todos los registros relacionados con el id de servicio enviado 1 o 2 o 3
                 $pub[]=$publication->profiles;
            }
            return $pub;

Pero no logro concretar que cuando activen dos o los las tres opciones solo me mande aquel usuario que cumpla con los dos o tres criterios.

introducir la descripción de la imagen aquí

Para el ejemplo que tengo al realizar esto me debería devolver:
el empleado con id 1 ya que es el único que cumple con los criterios de Limpia y Recoje, los demas usuarios uno solo Limpia y otro solo monitorea.

Tabla Empleados  Tabla Pivote                 Tabla Servicios
id Nombre        id empleado_id servicio_id   id nombre
1  Paula         1     1           1           1 Limpia
2  Maria         2     2           2           2 Recoge
3  Nina          3     1           2           3 Monitorea
                 4     3           3           

Espero darme a entender, agradesco sus comentarios

saludos.

One Answer

Consideremos que al tener lo siguiente:

$services = $request->services;

Estas obteniendo proveniente de tu vista un array con los posibles checkboxes elegidos, los cuales pueden ir de 0 a 3 valores con índices de 0 a 2.

Dicho lo anterior podemos establecer esto:

  • Si el conteo de elemento de la variable $services es 1 entonces debemos filtrar por solo un único valor
  • Si el conteo de elementos es 2 entonces tenemos 2 índices el 0 y 1 entonces ya debemos establecer 2 where uno principal y uno secundario para filtrar
  • Si el conteo nos da 3 entonces el usuario marcó todos los checkboxes y debemos filtrar con el uso de 3 where indicando en cada comparación la variable y el índice a recuperar
  • Ahora si el conteo diera 0 es que el usuario no ha elegido checkbox alguno y entonces deberás manejar que respuesta le vas a dar

Con una sintaxis de if/else puede quedar de esta forma:

$services = $request->services;

    if(count($services) === 1) {
        return Service::whereId($services)->get();
    } else if(count($services) === 2) {
        return Service::whereId($services[0])
                    ->orWhere("id", $services[1])
                    ->get();
    } else if(count($services) === 3) {
        return Service::whereId($services[0])
                    ->orWhere("id", $services[1])
                    ->orWhere("id", $services[2])
                    ->get();
    }

Edición final

Con base en que mencionas que una vez seleccionados los servicios necesitas los usuarios que que cumplan teniendo 1, 2 o los 3 servicios asignados, considero que puedes:

  • Asinar a una variable nueva el modelo y método query
  • Usaremos la variable definida anteriormente para que dentro del cuerpo del condicional encadenemos distintos métodos de búsqueda para componer la consulta
  • Filtrarás por medio del id a través del método findOrFail el o los servicios elegidos y en caso de encontrar una coincidencia de un o varios existentes....
  • Entonces le encadenas el nombre de la relación que definiste en el modelo Services la cual debería ayudarte a traer todos los usuarios, como no conozco dicha relación solo le coloqué el identificador relaciónNombre

    $services = $request["services"];
    
        $data = Service::query();
    
        if(count($services) === 1) {
            return $data->findOrFail($services[0])->relacionNombre;
        } else if(count($services) === 2) {
            return $data->findOrFail($services[0])
                        ->findOrFail($services[1])
                        ->relacionNombre;
        } else if(count($services) === 3) {
            return $data->findOrFail($services[0])
                        ->findOrFail($services[1])
                        ->findOrFail($services[2])
                        ->relacionNombre;
        }
    

Answered by BetaM on December 30, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP