如何在多个Rails模型上执行计算,逻辑应该在哪里?

时间:2012-03-02 09:55:41

标签: ruby-on-rails

我在Rails应用程序中有一个Invoice模型。 Invoice has_many产品和服务(两个独立的模型)。发票显示视图​​显示这些相关记录。

产品和服务都具有类似的结构,即项目,价格,数量。我可以将总计计算为price * quantity,我可以将产品的总价格计算为all.collect { |product| product.price * product.quantity },同样适用于服务。

如果我现在想要计算此发票上的产品+服务的总成本怎么办?

如何跨多个模型执行计算?计算逻辑应该去哪里?

我意识到一个解决方案是将产品和服务组合到一个模型中,但这不是一个选项。

我很遗憾从哪里开始,并且非常感谢一些指针,想法或有用文档的链接。

3 个答案:

答案 0 :(得分:2)

简而言之:使用模块。我想的是:

module TotalCalculator
  def sum
     map { |e| e.price * e.quantity }
  end
end

然后你可以:

class Product
  include TotalCalculator
end

当然,这只是一个微不足道的例子,命名很糟糕。顺便说一句,你可以得到图片。我会将所有逻辑放在像app/logiclib目录中的目录中。有时我将此技术模块称为业务逻辑模式,但我不知道它是否是正确的名称。

答案 1 :(得分:2)

只是为了检查:

  • Invoice has_many产品和服务
  • 产品有total_cost方法(或total_price)
  • 服务还有一个total_cost方法

并且您要问在哪里将发票的产品和服务的总价格逻辑放在哪里。正确的吗?

在这种情况下,将它放入发票中是正确的:

def total_cost_of_products
  products.collect { |product| product.price * product.quantity }
end

def total_cost_of_services
  services.collect { |services| service.price * service.quantity }
end

def total_price_of_products_and_services
  total_cost_of_products + total_cost_of_services
end

当然你可以更多地干这个,你可能想要对你的发票模型进行一些单元测试。请参阅lucapette的答案,了解重构和干涸的好方法

答案 2 :(得分:0)

您是否可以在发票型号total_cost上创建虚拟属性,然后将代码放在那里?

def total_cost 
  cost = #do your calculation here....
  return cost  
end