Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

ollie_123's avatar

How to call method from model in controller

Afternoon All

I hope you're all safe & well.

It was just a quick one. I've got an invoice & a payment gateway and the amount to be paid by the user is called from a method called totalSaleValue in the Order model and is displayed inside the view on the invoice.

In favour of security, rather than the user being able to inspect the amount in devtools and changing it before the invoice is paid, please could someone confirm how i could load the value inside of the controller so that even if the user changes the value in the view it wont affect how much they pay?

Hope that makes sense. I tried the following but was getting an undefined method...

public function charge(Request $request) {

        $orderId = $request->orderId;
        $orderAmount = Order::whereId($orderId)->totalSaleValue();

Thanks in advance all :)

0 likes
12 replies
tykus's avatar

Does Order::whereId($orderId) return an Order instance, or is it the Eloquent one of the magic where Builder methods?

Try a find or findOrFail to get the Order instance instead:

$orderAmount = Order::find($orderId)->totalSaleValue();
ollie_123's avatar

Hey @tykus the whereId was just one of those magic methods that saves a bit of typing.

Thank you for the advice. unfortunately though its still giving me an undefined method. :/

tykus's avatar

the whereId was just one of those magic methods that saves a bit of typing

But it does not execute the query, so you would be calling the totalSaleValue on an instance of Illuminate\Database\Eloquent\Builder, not on an instance of Order model!!!

Back to the issue, check that this Order::find($orderId) returns an Order model instance, and check that you do have the totalSaleValue method named correctly in the controller (i.e. matching the method name in the Order model)?

ollie_123's avatar

Hey @tykus

unfortunately not. I get an error of

Method Illuminate\Database\Eloquent\Collection::totalSaleValue does not exist.

It might help if i explain the layout of the tables.. I've got an orders table and a products table. The products belong to many orders etc etc.

The order total is calculated in a method in my order model public function getTotalSaleValueAttribute() counting the value of all of the products related to that order.

It works inside of the view when i call $order->totalSaleValue but for some reason i cant get it going in the controller.

Thank you in advance.

tykus's avatar

Why do you get a Collection, is $orderId an array? Did you use find to get the Order instance?

Prokosa's avatar
Prokosa
Best Answer
Level 1
$orderId = $request->orderId;
$orderAmount = Order::whereId($orderId)->totalSaleValue();

1 .Try this

$orderId = $request->orderId;
$orders= Order::whereId($orderId)->get();
foreach($orders as $order){
$order->totalSaleValue()
}

or

$orderId = $request->orderId;
$order = Order::whereId($orderId)->first();
$orderAmount=$order->totalSaleValue();

or

$orderId = $request->orderId;
$order = Order::find($orderId);
$orderAmount=$order->totalSaleValue();

I think totalSaleValue() method can be called for single object Order model. Are you trying to do this with lot objects

2 .Case custom attribute model

Try this

$orderId = $request->orderId;
$orders= Order::whereId($orderId)->get();
foreach($orders as $order){
$order->total_sale_value
//or $order->totalSaleValue
}
nbj's avatar

Just to clarify, when you create a computed property like the method getTotalSaleValueAttribute() the correct way of getting the value on the object is referencing it like this $order->total_sale_value;

Laravel does some behind-the-scene magic to create object properties out of methods name get<PROPERTY_NAME>Attribute() where <PROPERTY_NAME> is pascal-cased in the method signature, but referenced snake-cased when accessing its value on the object

ollie_123's avatar

Hey @prokosa that is just the ticket. There really is multiple ways to skin a mango lol.

Option 2 made the most sense and i can see where i was going wrong now. I was calling the order and the value all in one query where as i should have called the order then as you suggested and then call the value based on the order. Appreciate the help.

@nbj thanks for the top tip :) i will bear that in mind for future.

Thanks all :)

ollie_123's avatar

Out of curiosity, if i wanted to sum of all orders, why would i get an error of

Call to undefined method App\Order:: total_sale_value;

Currently i've got

$orders = Order::whereNotNull('paid_at')->get();
        foreach($orders as $order){
            $order->total_sale_value();
        }

but it spits out every field of each order in the view. However if i put

$orders = Order::whereNotNull('paid_at')->get();
        foreach($orders as $order){
            $order->total_sale_value;
        }
// I get an error of...
App\Order::total_sale_value must return a relationship instance.

Please can someone advise where i'm going wrong.

Thank you in advance.

nbj's avatar

@oli_d111 Based on the usage of a computed property: total_sale_value I think you could try something like this:

$sum = Order::whereNotNull('paid_at')->get()
    ->sum('total_sale_value');

Or if sum does not acknowledge the computed property as key, then go for one of the more explicit versions:

$sum = Order::whereNotNull('paid_at')->get()
    ->sum(function ($order) {
        return $order->total_sale_value;
    });

or

$sum = Order::whereNotNull('paid_at')->get()
    ->reduce(function ($accumulator, $order) {
        $accumulator += $order_total_value;
        
        return accumulator;
    });

Please or to participate in this conversation.