Расчет суммы заказов в Rails

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

По сути, пользователь может выбирать продукты, которые добавляются к его заказу, а затем сохраняются как order_products. У меня есть следующие модели (указаны только актуальные поля):

#products table has fields name, price
class Product 
end 

#orders table has field total
class Order
  has_many :order_products
  accepts_nested_attributes_for :order_products
end

#orderproducts table has fields order_id, product_id, qty
class OrderProduct
  belongs_to :order
  belongs_to :product
end

Как лучше всего суммировать товары для создания общей суммы заказа? Очевидно, вы не можете просто указать скрытое поле в форме заказа, так как кто-то может этим манипулировать. Я думал о том, чтобы сделать что-то вроде этого:

class Order
  has_many :order_products
  accepts_nested_attributes_for :order_products
  before_save :calc_total

  def calc_total
    self.total = order_products.product.sum(&:price)
    #or should this be order_products.sum(&product.price) or similar?
  end 
end

Но это не похоже на правильный синтаксис. Может быть, я не могу использовать функцию «сумма», и мне нужно просто просмотреть order_products и найти цену в модели продукта? Конечно, это довольно распространенный сценарий - правильно ли я поступаю?

Кроме того, учитывая, что цены на товары могут измениться, лучше ли хранить цену каждого товара в таблице товаров для заказа во время заказа? В этом случае мог бы я просто добавить еще одну функцию before_save в модель OrderProduct, найти текущую цену из модели Product, умножить ее на qty и сохранить как значение product_total?

И, наконец, что произойдет, если продукт будет удален, если на него ссылаются order_products? Это вызовет проблемы? Или у меня все в порядке, если я кэширую необходимые данные о продукте в таблице order_products во время заказа.

Спасибо!


person Dave    schedule 08.09.2013    source источник


Ответы (1)


У меня это работает со следующим, но не уверен, что это лучший способ

def calc_totals
  self.total = 0
  order_products.each do |op|
    self.total += op.product.price * op.qty
    op.item_price = op.product.price
    op.item_total = op.product.price * op.qty
  end
end
person Dave    schedule 08.09.2013