轨;总和

时间:2016-12-09 09:58:47

标签: ruby-on-rails ruby

我想以更像Ruby的方式重构下面的代码。

def cal_total
    total = nil
    items.each do |item|
      total = total + item.itemable.amount
    end
    total
end

基本上只是迭代对象,获取每个数量,然后返回总数。 有什么想法吗?

更新

total = item.itemable.amount是正确的。

6 个答案:

答案 0 :(得分:1)

您可以尝试以下操作:

items.map(&:amount).inject(0, &:+)

确切的语法取决于您的代码。虽然不一定是Ruby方式,但它更简洁实用。

答案 1 :(得分:1)

您可以执行此操作,我希望使用includes来加载,以避免n + 1查询问题

items = Item.includes(:itemable) 
total = items.map{ |item| item.itemable.amount }.sum

希望有所帮助!

答案 2 :(得分:1)

重构时还可以做一件事。

在项目模型中,您可以将金额方法委托给可迭代的

class Item
  delegate :amount, to: :itemable, prefix: true, allow_nil: true
end

现在,您可以在没有.运算符的情况下获得金额。

items.map{ |item| item.itemable_amount }.sum

使用prefix: false,您可以写

items.map{ |item| item.amount }.sum

答案 3 :(得分:0)

试试这个关联:

items.map(&:itemable).sum(&:amount)

OR

items.map { |i| i.itemable.amount }.sum

答案 4 :(得分:0)

您可以使用sum

items.map{ |item| item.itemable.amount }.sum

答案 5 :(得分:0)

你可以通过这种方式得到总和,我认为这是最佳实践,也是性能最有效的方法

items.map(:&itemable).pluck(:amount).reduce(:+)