Use a model (resource) attribute (accessor) with metrics in Laravel Nova

I have a MySQL table called purchases and a model called Purchase in Laravel that is related to it. My table has two columns, quantity and unit_cost. The total cost of a purchase is not a column in my table. Instead, it is defined by an accessor in Laravel that multiplies unit_cost by quantity and returns it as total_cost.

Now I am trying to define a trend metric in Laravel nova that is supposed to output the value of my daily sales in the selected range. When I try to use return $this->sumByDays($request, Purchase::class, 'total_cost') it gives me an error that says total_cost is not a column.

Fair enough! So, I tried to use Purchase::selectRaw(DB::RAW('unit_cost * quantity AS total_cost')) in the second argument, but it didn’t work. I saw multiple posts, none of them could solve the problem of accessing a model accessor in Laravel Nova metrics. Any help is appreciated.


Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

Unfortunately you can’t use the built-in sumByDays helper function.

But good news! You can still implement it yourself within the calculate function. Just make sure your function returns a LaravelNovaMetricsTrendResult.

Something like this:

$purchases = DB::table('purchases')
    ->select(DB::raw('quantity * unit_cost as total_cost'))
    ->groupBy(DB::raw('DATE(created_at) DESC'))

return new TrendResult()

I don’t have time to test this at the moment but it should get you started.

Method 2

While trying to fix this problem, I checked through the sum by day or hours code and I realised that the column is an instance of Query Expression.

So that means you can still use the built in nova sum by days.

Make sure you import use IlluminateDatabaseQueryExpression;

Just do this

$xpression = new Expression('quantity * unit_cost');
return $this->sumByDays($request, Purchase::class, $xpression);

It worked for me easily, I hope it does for others too.

The expression could be used in various ways in my case it was to perform a different calculation.

All methods was sourced from or, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Notify of

Inline Feedbacks
View all comments
Would love your thoughts, please comment.x