es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Consulta elocuente para addSelect y whereIn para tablas de datos relacionales.

Estoy usando Laravel 8. Tengo dos tablas que están relacionadas. Una es ‘customers’ (clientes) y la otra es ‘jobs’ (trabajos). Un cliente puede tener un historial de muchos trabajos. Estoy tratando de construir una consulta utilizando Eloquent que contenga un cliente y todos sus trabajos en una sola colección. He intentado varias cosas y

La mayoría de las veces me encuentro con el siguiente error:

SQLSTATE[21000]: Cardinality violation: 1242 Subquery returns more than 1 row (SQL: select customers.*, (select type from jobs where jobs.type in (HVAC, Select)) as jobType from customers)

Ahora, estoy bastante seguro de que esto está sucediendo porque hay más de un trabajo para el cliente, pero no sé cómo evitar que esto sea un problema. En realidad, es lo que estoy tratando de lograr.

He intentado algunas cosas:

$jobs = Job::where(‘class’,’LIKE’,’%’.$request->class.’%’)
->whereBetween(‘date_booked’,[$request->start_date, $request->end_date])
->join(‘customers’, ‘customers.location_number’, ‘=’, ‘jobs.location_number’)
->join(‘notes’, ‘notes.location_number’, ‘=’, ‘jobs.location_number’)
->where(‘jobs.type’,$type)
->take(’30’)->get();

También he intentado (como una prueba muy simple):

$jobs = Customer::addSelect([‘jobType’ => Job::select(‘type’)
->whereIn(‘jobs.type’,$type)])
->get();

pero no parece estar funcionando.

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    Para recuperar un cliente y todo su historial laboral en una sola colección utilizando Eloquent en Laravel 8, puedes definir una relación uno a muchos entre los modelos Customer y Job. En tu modelo Customer, agrega el siguiente método:

    public function jobs()
    {
        return $this->hasMany(Job::class);
    }
    

    Luego, para recuperar un cliente y sus empleos, puedes usar el método with() para cargar ansiosamente la relación jobs:

    $customer = Customer::with('jobs')->find($customerId);
    

    Esto recuperará al cliente con el ID especificado y todos sus empleos relacionados en una sola colección, a la cual puedes acceder con $customer->jobs.

    Si necesitas filtrar los empleos por tipo, puedes agregar una restricción where() a la relación:

    public function jobs()
    {
        return $this->hasMany(Job::class)->where('type', $jobType);
    }
    

    Luego, al recuperar el cliente, solo se incluirán los empleos con el tipo especificado:

    $customer = Customer::with('jobs')->find($customerId);
    

    Ten en cuenta que $jobType debe ser una variable que contenga el tipo de empleo por el cual deseas filtrar.

    Utilizar la relación anterior y el enfoque de carga ansiosa generalmente es más fácil y eficiente que tratar de construir una única consulta que recupere clientes y sus empleos con subconsultas SQL.

Comments are closed.