2016-12-29 3 views
1

Я пытался вычислить общую сумму заказа с помощью этого: Laravel Eloquent: Best Way to Calculate Total Priceрасчет Laravel Цена

Я хочу, чтобы расчет должно быть сделано в модели, так что я могу использовать его в нескольких контроллерах.

Мой код выглядит следующим образом:

class Order extends Model 
{ 
    public function customer() 
    { 
     return $this->belongsTo('App\Customer'); 
    } 

    public function orderItems() 
    { 
     return $this->hasMany('App\OrderItem'); 
    } 

    public function total() 
    { 
     return $this->orderItems->sum(function($orderItem) 
      { 
       return $orderItem->net_price; 
      }); 
    } 
} 

Так что я думаю, что я сделал все так же, как в примере, но я получаю следующее сообщение об ошибке:

ErrorException in Model.php line 2696: Relationship method must return an object of type Illuminate\Database\Eloquent\Relations\Relation

Любая помощь будет высоко оценили.
Спасибо.

+0

прямо сейчас им не называть его вообще и получить ошибку в любом случае. – Joha

+0

Прежде, чем я позвонил из представления с {{$ order-> total}} и {{$ order-> total()}} – Joha

ответ

0

Joha, я бы очень тщательно использовал функцию sum в коллекции, когда вы работаете с десятичными значениями. Это не будет иметь значения, если вы используете целочисленные значения.

Вы можете обнаружить, что функция суммы иногда просчитывает сумму и оставляет вас причудливыми номерами, такими как 59.999999999998184. Это связано с тем, что десятичные операции не очень стабильны на компьютерах, поэтому вы должны обходить каждый элемент и использовать bcmath вместо этого. Даже если вы не испытываете этого сейчас, по мере того, как приложение растет, это станет проблемой.

Здесь будет более безопасным & точный пример:

class Order extends Model{ 

    public function customer() 
    { 
     return $this->belongsTo('App\Customer'); 
    } 

    public function orderItems() 
    { 
     return $this->hasMany('App\OrderItem'); 
    } 

    public function getTotalAttribute() { 
     $totalPrice = 0; 

     foreach ($this->orderItems as $orderItem) { 
      $totalPrice = bcadd($totalPrice, $orderItem->net_price, 2); 
     } 

     return $totalPrice; 
    } 
} 

Я хотел бы также реорганизовать функцию в качестве атрибута, как показано в примере кода. Это позволяет вам получить доступ к $order->total, как если бы это был атрибут модели.

+0

благодарим вас за ответ, как/где выполняется рефакторизация, поэтому я могу использовать его как атрибут? просто вызвав функцию get .... Атрибут()? – Joha

+0

Рефакторизация выполняется в коде, содержащемся в моем ответе. Как это работает, так как имя функции «getTotalAttribute()». Laravel автоматически выбирает это, и теперь в вашем представлении/контроллере, где у вас есть заказ, вы можете получить доступ к '$ order-> total', и он вернет значение функции getTotalAttribute(). Имеет ли это смысл? – SixteenStudio

+0

Да, это имеет смысл, и я уже пробовал это. Спасибо! – Joha

0

насчет:

public function total() { 
    return $this->orderItems->sum('net_price'); 
} 
+0

Я пробовал, и я получаю ту же ошибку. – Joha

+0

о втором варианте в этом ответе. '' '$ this-> orderItems() -> sum (DB :: raw ('net_price'));' '' – CUGreen

+0

по-прежнему те же ошибки ... – Joha

0

Проблема заключается в вас hasMany отношениях. Попробуйте это:

public function orderItems() 
{ 
    return $this->hasMany(App\OrderItem::class, 'order_id'); 
} 

Конечно, вы должны изменить order_id имя, которое хранит информацию в таблице в OrderItem в.

+0

Подождите секунду, я попробую. но я не думаю, что это проблема, потому что в контроллере я могу перебирать orderitems с помощью foreach ($ order-> orderItems как orderItem) {...} – Joha

+0

, так как «идентификатор заказа» - это внешний ключ в моей таблице заказов. должен работать по умолчанию так, как я имел это раньше, не так ли? – Joha

+0

Он должен. Но, поскольку я не видел других проблем, я думал, что мы должны попробовать. –

0

Кажется, что функция правильная, и проблема в том, что вид, из которого я его назвал, не был загружен правильно после того, как я его изменил. вызов в представлении должен быть {{$ order-> total()}}

Спасибо за помощь, ребята!

Смежные вопросы