Problema al utilizar el método "withCount" en Laravel Nova

Publicado por Lynn
hace 4 meses

Tengo un problema al utilizar el método "withCount" en Laravel Nova. Estoy tratando de obtener la cantidad de comentarios de un modelo en una tabla de Nova, pero cuando utilizo el método "withCount" me genera un error.

Este es mi código en el fichero "Nova/Comment.php":

<?php

namespace App\Nova;

use Illuminate\Http\Request;
use Laravel\Nova\Fields\ID;
use Laravel\Nova\Fields\Text;
use Laravel\Nova\Fields\Number;
use Laravel\Nova\Fields\BelongsTo;
use Laravel\Nova\Fields\DateTime;
use Laravel\Nova\Http\Requests\NovaRequest;
use Laravel\Nova\Resource;

class Comment extends Resource
{
    /**
     * The model the resource corresponds to.
     *
     * @var string
     */
    public static $model = 'App\Models\Comment';

    /**
     * The single value that should be used to represent the resource when being displayed.
     *
     * @var string
     */
    public static $title = 'id';

    /**
     * Get the fields displayed by the resource.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return array
     */
    public function fields(Request $request)
    {
        return [
            ID::make()->sortable(),
            Text::make('Content'),
            Number::make('Likes'),
            BelongsTo::make('User'),
            DateTime::make('Created At')->sortable(),
        ];
    }

    /**
     * Get the cards available for the request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return array
     */
    public function cards(Request $request)
    {
        return [
            (new Metrics\CommentsCount)->width('1/3'), // this is the card using withCount
        ];
    }
}

Y este es el error que obtengo al intentar acceder al recurso en Laravel Nova:

ErrorException
Call to undefined method Illuminate\Database\Eloquent\Collection::withCount()

The first argument passed to the "withCount" method must be an array or a string.

No entiendo por qué me genera este error si estoy utilizando el método correctamente. ¿Alguna idea de lo que podría estar pasando? Gracias de antemano.

Laravel Nova withCount relación
Respuesta de Gordon Shumway
hace 4 meses

¡Hola Lynn! Con gusto te ayudaré a resolver tu problema.

El error que estás viendo se debe a que estás intentando usar el método withCount() en una instancia de Collection y este método está disponible únicamente para las instancias de la clase Illuminate\Database\Eloquent\Builder o Illuminate\Database\Query\Builder.

Por lo que entiendo, deseas agregar un conteo de una relación a tus resultados en Laravel Nova; sin embargo, basándonos en el código que proporcionaste, parece que estás intentando hacerlo dentro de una métrica (Metrics\CommentsCount). Estas métricas generalmente están destinadas a cálculos personalizados y deberían devolver un resultado en lugar de utilizar el método withCount() directamente.

Si lo que necesitas es añadir un conteo de una relación (por ejemplo, el número de comentarios asociados a un modelo Post), esto se debería realizar en la definición de los campos del recurso Nova, no en la métrica. Por ejemplo:

// En tu modelo Post en caso de que quieras contar comentarios relacionados
use Laravel\Nova\Fields\Number;

class Post extends Resource {
    // ...

    public function fields(Request $request) {
        return [
            // Otros campos...
            Number::make('Comments Count', function () {
                return $this->comments()->count();
            }),
        ];
    }

    // ...
}

Si realmente necesitas realizar un conteo agregado dentro de una métrica, deberías hacerlo manualmente en su método calculate() en lugar de usar withCount(). Recuerda que este método calculate() debe devolver una instancia de Laravel\Nova\Metrics\ValueResult o alguna otra métrica válida. Aquí tienes un ejemplo esquemático:

// En tu Metrics/CommentsCount.php
use Laravel\Nova\Metrics\Value;
use Laravel\Nova\Http\Requests\NovaRequest;

class CommentsCount extends Value {
    // ...

    public function calculate(NovaRequest $request) {
        // Realizas la consulta necesaria para obtener el conteo
        $count = \App\Models\Comment::query()->count();

        // Devuelves un resultado de métrica con ese conteo
        return $this->result($count);
    }

    // ...
}

Espero que te ayude a resolver el problema que estás enfrentando. Si necesitas aclarar más dudas o tu caso es diferente, por favor, proporciónanos más detalles sobre la relación que estás intentando contar y cómo estás estructurando tus recursos y métricas en Nova. ¡Ánimo con tu proyecto!