That just creates the attribute. getTotalPriceAttribute gets the attribute total_price on your model, but allows you to modify it first. In your case, this attribute doesnt exist so you get an error. setTotalPriceAttribute creates the attribute. Then you should be able to do this:
public function getTotalPriceAttribute() {
return $this->quantity * $this->price;
}
public function setTotalPriceAttribute() {
// I don't know the code here
}
public function getTotalPriceAttribute() {
// you dont need this method
}
public function setTotalPriceAttribute() {
return $this->quantity * $this->price;
}
sum() is an aggregate function which will work if column is there in database. For computed property, above should work for you unless, there's something wrong with model itself. Show your model class ...
class Order extends Model
{
public $primaryKey = 'pno';
public $timestamps = false;
protected $fillable = ['pno','quantity','unitprice'];
public function getTotalPriceAttribute() {
}
public function setTotalPriceAttribute() {
return $this->quantity * $this->unitprice;
}
}
You don't even need an accessor, can be simple function like totalPrice() , but if you wish
@zachleigh Trouble visualising, why are you insisting on mutator than accessor.
class Order extends Model
{
public $primaryKey = 'pno';
public $timestamps = false;
protected $fillable = ['pno','quantity','unitprice'];
public function getTotalPriceAttribute() {
return $this->quantity * $this->unitprice;
}
}
// and access it like $order->total_price // sum will not work
Probably you are unsure at this point of what you need, as i don't understand where the above would be applicable, But you will figure it out later ....
If its only the above query that you need then ...
total = DB::table('ordertable')->sum(DB::raw(' quantity * unitprice '));
class Order extends Model
{
public $primaryKey = 'pno';
public $timestamps = false;
protected $fillable = ['pno','quantity','unitprice'];
public function getTotalPriceAttribute() {
return $this->quantity * $this->unitprice;
}
}
You should be able to get the new total_price attribute by doing $order->total_price. Does that work? It should.
Now if you want the sum of the total prices of a list of orders (which is clearly what you want), you can't use the new total_price accessor for that. But you can just loop through your orders and sum them up yourself?
@shanely@Prullenbak
As an alternative to summing in a for loop, you can call sum with your accessor if you first receive a collection. In your case, something like this should work.
I don't understand, loop, no loop, and what is the sum() function on collection is doing behind the scene. array_reduce() ???
And on a side note ,
$ordersTotal = Order::all()->sum('total_price');
is highly inefficient way to deal with this, you don't load entire table in memory to calculate the sum, unless, its very complex calculation and beyond the scope of database.
@d3xt3r Yes sum does call array_reduce behind the scenes. Yes in this case, it is not likely the best way to deal with this but it is the only way that I know of to call sum on a custom attribute. Per your suggestion, the raw db query would be better in this case. I was just trying to give additional options to answer the question by the OP and let them decide. To be honest, assuming that $orders represented all orders, I'm still unsure as to why sum was being called on a single record in the foreach loop.
@ctroms Ya, its a messed up question, but glad that you agree on calculating the sum within the db call itself, if they are capable of, then why not utilise it :)