nova-issues icon indicating copy to clipboard operation
nova-issues copied to clipboard

Value Metrics Count $groupBy no longer allows DB::Raw expression

Open cparkinsonMYCM opened this issue 10 months ago • 3 comments

  • Laravel Version: 10.48.9
  • Nova Version: 4.33.3
  • PHP Version: 8.1

Description:

We have a couple of metrics whose calculate method looks like this:

return $this->count($request, Model::withoutGlobalScopes(), DB::Raw("ISNULL(`some_id`)"))
	->label(fn($value) => $value ? "A" : "B")
	->colors([
		"A" => "#66FF66",
		"B" => "#6666FF",
	]);

These used to work but at some point it seems the formatAggregateResult method has changed to explode the $groupBy value assuming it's a string and then directly accessing the $groupBy column, so now we can't group by the calculated field.

cparkinsonMYCM avatar Apr 26 '24 11:04 cparkinsonMYCM

Unable to reproduce the issue, please provide full reproducing repository based on fresh installation as suggested in the bug report template (or you can refer to https://github.com/nova-issues for example)

crynobone avatar Apr 26 '24 12:04 crynobone

provide full reproducing repository based on fresh installation

I don't have enough time to go through that setup, so we'll just work around it instead... Feel free to close.

But for context, if it matters.

Passing a DB::Raw('...') expresssion as the $groupby gives this error:

local.ERROR: explode(): Argument #2 ($string) must be of type string, Illuminate\Database\Query\Expression given {"userId":"1eef1014-ebe2-6d6a-a70e-7912c197fbd9","exception":"[object] (TypeError(code: 0): explode(): Argument #2 ($string) must be of type string, Illuminate\\Database\\Query\\Expression given at /var/www/html/vendor/laravel/nova/src/Metrics/Partition.php:126)

Here:

/**
     * Format the aggregate result for the partition.
     *
     * @param  \Illuminate\Database\Eloquent\Model  $result
     * @param  string  $groupBy
     * @return array<string|int, int|float>
     */
    protected function formatAggregateResult($result, $groupBy)
    {
        $key = with($result->{last(explode('.', $groupBy))}, function ($key) {
            return Util::value($key);
        });

        if (! is_int($key)) {
            $key = (string) $key;
        }

        return [$key => $result->aggregate ?? 0];
    }

cparkinsonMYCM avatar Apr 26 '24 12:04 cparkinsonMYCM

The doc block parameter of $groupBy is and has always been string. Illuminate\Database\Query\Expression however no longer has __toString() method since Laravel 10 which would cause this issue.

crynobone avatar May 06 '24 05:05 crynobone

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

github-actions[bot] avatar May 29 '24 00:05 github-actions[bot]