【问题标题】:Rails; sum total导轨;总和
【发布时间】:2017-04-24 18:30:37
【问题描述】:

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

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

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

更新

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

【问题讨论】:

  • 什么是 itemable,也可以通过单个查询来完成
  • 项目与其他模型具有多态关系。
  • @TSH 添加您的关联。 items.itemable - 这行得通吗?
  • @dp7 抱歉我更新了问题。
  • @TSH 添加了答案

标签: ruby-on-rails ruby


【解决方案1】:

您可以通过这种方式获得总和,我认为这是最佳实践,并且在性能方面最有效

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

【讨论】:

    【解决方案2】:

    在重构时,您还可以做一件事。

    在 Item 模型中,您可以将 amount 方法委托给 itemable

    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】:

      为你的协会试试这个:

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

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

      【讨论】:

      • 这不起作用NoMethodError: undefined method +'
      • @RSB 我的第一个编辑是items.map(:itemable).collect(&:amount).sum - 然后我想为什么要使用mapcollect 两次,最好把它放在一个块内。然后这是一个编辑:)
      • @TSH 我的第一个答案中有一个错字,因为你得到了NoMethodError: undefined method +',试试这个items.map(&:itemable).sum(&:amount)
      • @Downvoter:请告诉我如何改进答案。
      【解决方案4】:

      您可以使用sum

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

      【讨论】:

        【解决方案5】:

        你可以这样做,我渴望加载使用includes以避免n + 1查询问题

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

        希望有帮助!

        【讨论】:

          【解决方案6】:

          您可以尝试以下方法:

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

          确切的语法取决于您的代码。虽然不一定是 Ruby Way,但它的风格更加简洁和实用。

          【讨论】:

          • 也可以写成items.map(&:amount).reduce(&:+)或Rails中的items.map(&:amount).sum
          • items.itemable.map(&:amount).inject(0, &:+)
          • @user000001,没错,injectreduce 在 ruby​​ 中几乎是一样的。
          • @Sid:它们完全一样
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多