Rubyのように以下のコードをリファクタリングしたいと思います。Rails;総計
def cal_total
total = nil
items.each do |item|
total = total + item.itemable.amount
end
total
end
基本的にオブジェクトを反復し、各量をフェッチして合計を返します。
更新
total = item.itemable.amount
は正しいです。
Rubyのように以下のコードをリファクタリングしたいと思います。Rails;総計
def cal_total
total = nil
items.each do |item|
total = total + item.itemable.amount
end
total
end
基本的にオブジェクトを反復し、各量をフェッチして合計を返します。
更新
total = item.itemable.amount
は正しいです。
あなたは次のことを試すことができます。
items.map(&:amount).inject(0, &:+)
正確な構文は、あなたのコードに依存します。必ずしもRuby Wayではありませんが、より簡潔で機能的なスタイルです。
'items.map(&:amount).reduce(&:+)'またはRails 'items.map(&:amount).sum'としても書けます。 – user000001
' items.itemable.map (&:amount).inject(0、&:+) ' – Kris
@ user000001これは本当ですが、' inject'と 'reduce'はルビーでほとんど同じです。 – Sid
あなたがこれを行うことができ、私は
items = Item.includes(:itemable)
total = items.map{ |item| item.itemable.amount }.sum
n + 1
クエリの問題を回避するために希望をincludes
を使用して積極的なロードしていますそれは助ける!
あなたはリファクタリング中に行うことができますもう一つはありsum
items.map{ |item| item.itemable.amount }.sum
を利用することができます。アイテムのモデルでは
、あなたは今、あなたは.
オペレータなしで量を得ることができ
class Item
delegate :amount, to: :itemable, prefix: true, allow_nil: true
end
をitemableする金額メソッドを委任することができます。あなたが書くことができますprefix: false
で
items.map{ |item| item.itemable_amount }.sum
、
items.map{ |item| item.amount }.sum
あなたは合計をこのように取得し、私はこれがベストプラクティスとパフォーマンスの問題の中で最も効率的であると考えることができます
items.map(:&itemable).pluck(:amount).reduce(:+)
アイテム化可能なものは、単一のクエリでも実行できます – RSB
アイテムは他のモデルと多相関係を持っています。 – Tosh
@TSHあなたの関連付けを追加してください。 'items.itemable' - これは機能しますか? – dp7