[Resuelto] Consultar múltiples tablas relacionadas en Laravel (Eloquent)

Publicado hace 9 meses por ridier.ayala

Quiero realizar una consulta usando el Motor de Eloquent a la tabla Movimientos

Las relaciones entre las tablas involucradas son las siguientes:

  • issues (n-m) users
  • issues (1-n) movements
  • issues (1-n) policies
  • policies (1-n) movements

La super consulta que deseo conseguir, es todos los movimientos(movements) pertenecientes a sus pólizas (policies) y que estos a su vez pertenecen a las emisiones(issues) en estado ['review', 'checked', 'approved'], del usuario actualmente logeado en el sistema. El usuario logeado en el sistema unicamente tiene una relación muchos a muchos con la tabla emisiones(issues).

Y como si fuera poco.., tengo además un buscador que por medio del campo "code" de la tabla pólizas(policies), me debe filtrar dicha consulta.

DE momento lo he conseguido resolver usando el siguiente código, pero sin usar eloquent sino por medio de las relaciones.

$code = $request->get('code');
$policies = currentUser()->issues()
	->whereIn('status', ['review', 'checked', 'approved'])
	->orderBy('id', 'DESC')
	->whereHas('policies', function($query) use ($code){
	if($code){
		$query->where('code', 'LIKE', "%$code%");
	}
	})
	->paginate();

$movements = [];
foreach ($policies as $policy) {
	$movements[] = $policy->movements()->paginate();
}

return view('movement.index', compact('movements'));

Esto funciona ineficientemente ya que al tratar de renderizar estos datos en la vista me toca usar dos foreach() y cuando intento utilizar métodos de Laravel como el paginate(), me lanza errores ya que lo que tengo es un array y no una colleción de datos.

@forelse($movements as $key)
    @foreach($key as $movement)
        <tr>
            <td>{{ $item->name_client }}</td>
            <td>{{ $policy->code }}</td>
            <td>{{ $item->branchsIndividual($policy) }}</td> 
            <td>{{ $item->name_insurer }}</td>   
            <td>{{ $item->date_since }}</td>   
            <td>{{ $item->date_until }}</td>
            <td>{{ $movement->policy->issue->name_client }}</td>
            <td>{{ $movement->policy->code }}</td>
            <td>{{ $movement->date_movement }}</td>
            <td>{{ $movement->move->type_name }}</td>
            <td>{!! $movement->details !!}</td>
        </tr>
    @endforeach
@empty
    <tr>
        <td colspan="8">No hay pólizas aprobadas en el sistema</td>
    </tr> 
@endforelse
Mejor respuesta Marcada por Ecuador ridier.ayala

italomoralesf hace 9 meses

Está díficil comprender que quieres lograr, pero si entendí bien esta consulta te puede ayudar... Para que no navegues entre tantas colecciones.

En el controlador haría lo siguiente:

        $code = $request->get('code');
        $movements = Movement::orderBy('id', 'DESC')
            ->whereHas('policy', function ($query) use ($code) {
                if($code){
                    $query->where('code', 'LIKE', "%$code%");
                }
                $query->whereHas('issue', function($query) {
                    $query->whereIn('status', ['review', 'checked', 'approved']);
                    $query->whereHas('users', function($query) {
                        $query->where('user_id', currentUser()->id);
                    });
                });
            })
            ->paginate();

        return view('movement.index', compact('movements'));

A través del whereHas ves como navego entre tablas, (toma en cuenta que deben existir las relaciones en las entidades)

Y en la vista imprimiría así:

            @forelse($movements as $movement)
                <tr>
                    <td>{{ $movement->policy->issue->name_client }}</td>
                    <td>{{ $movement->policy->code }}</td>
                    <td>{{ $movement->date_movement }}</td>
                    <td>{{ $movement->move->type_name }}</td>
                    <td>
                        @foreach($movement->branches as $branch)
                            {{ $branch->name }} <br>
                        @endforeach
                    </td>
                    <td>{!! $movement->details !!}</td>
                    <td>
                        <a href="{{ route('movements.show', $movement->id) }}">
                            <span class="fa fa-eye"></span>
                        </a>
                    </td>
                </tr>   
            @empty
            <tr>
                <td colspan="5">No hay movimientos pendientes</td>
            </tr>
            @endforelse

Espero esto te ayude mi amigo, si algo no comprendes o yo te entendí mal me haces saber.

Lo que hice fue copiar tu código y editar según comprendí.