Para lograr lo que deseas, puedes usar el método withCount en lugar de with. Esto te permitirá obtener el número de elementos relacionados sin cargar los propios elementos. Este método es especialmente útil cuando solo necesitas contar los elementos relacionados y no trabajar directamente con ellos (evitas cargar datos innecesarios).
Aquí tienes un ejemplo de cómo podrías hacerlo:
$customers = Customer::withCount('quotes')->get();
Esto agregará una propiedad quotes_count a cada modelo Customer en la colección resultante, la cual contiene el número de quotes relacionados con cada Customer.
Luego, puedes acceder a esta cuenta de elementos de quotes para un cliente específico de la siguiente manera:
foreach ($customers as $customer) {
echo $customer->quotes_count;
}
Cada Customer en la colección tendrá una propiedad quotes_count que puedes utilizar para mostrar el número de quotes relacionados.
Si deseas cargar también otra relación completa como invoices mientras usas withCount para quotes, puedes hacerlo así:
$customers = Customer::with('invoices')->withCount('quotes')->get();
De esta manera, estarás cargando todas las facturas relacionadas con cada cliente y, al mismo tiempo, contando el número de quotes para cada uno, todo en una operación optimizada de eager loading.
eager loading de la cuenta de la relación eloquent a un segundo nivel
El segundo caso que comentas puede ser un poco más complejo, porque withCount no permite acceder a la cuenta de las relaciones de relaciones... no sé si me explico.
Entonces, para obtener la cuenta del número de productos en cada factura mientras cargas las facturas asociadas a cada cliente, puedes utilizar la función with para cargar las facturas y la función withCount para contar los productos en cada factura. Sin embargo, dado que deseas contar los productos dentro de una relación anidada (facturas de un cliente), necesitas hacer un poco más de trabajo para especificar correctamente la relación anidada.
Puedes lograr esto utilizando el método with y pasando una función de callback para especificar la relación anidada y aplicar withCount a esa relación anidada. Aquí te muestro cómo podrías hacerlo:
$customers = Customer::with(['invoices' => function ($query) {
$query->withCount('products');
}])->get();
En este código, estamos cargando todos los clientes y, para cada cliente, cargamos sus facturas. Para cada factura, en lugar de cargar todos los productos asociados, estamos contando el número de productos y este conteo se agregará a cada modelo de factura como una propiedad products_count.
Luego, puedes acceder a la cuenta de productos para cada factura de un cliente específico de la siguiente manera:
foreach ($customers as $customer) {
foreach ($customer->invoices as $invoice) {
echo $invoice->products_count;
}
}
Cada Invoice en la colección de facturas de cada Customer tendrá una propiedad products_count que puedes utilizar para mostrar el número de productos asociados con esa factura.
Espero haberte contestado bien, sin haber probado los ejemplos, ya me dirás si te funciona todo correctamente.