2017-05-11 7 views
0

クイックRailsの質問。私はコレクションを持っているときにいくつかのRailsメソッドのクエリデータベースなぜ

だから私は、データベースから取得し、のようなもののコレクションを持っている:

a = Invoice.all 

をその後、私はそのコレクション上のすべての金額の合計を持ちたい:

a.sum(:amount) 

それは作品とリターン適切な値、mu質問は、それが既にコレクション全体へのアクセス権を持っていて、コレクションからレコードを見ることができるときに、Railsが.sum()の部分で2番目の呼び出しを行うのはなぜですか?だから私はコレクションを持っている任意のヘルプ

答えて

2

ため

おかげで、いや、それは「膨張」コレクション(それは任意のオブジェクトが含まれていないではありませんデータベース

a = Invoice.all 

から検索)。代わりに、どのような種類のオブジェクトがこのクエリを満たすかを記述する、リレーション/クエリオブジェクトです。

コード内に2行しかない場合は、sumというクエリが1つだけ表示されます。あなたが2番目のクエリが表示された場合は、請求書(またはそのような何か)にループし、いくつかの他のコードがありますでなければなりません

a.each do |invoice| 
    ... 
end 
+0

感謝を利用することができるのActiveRecordクエリを発射したくない場合はsumSUM("invoices"."amount")

と異なるクエリを起動します。 'to_a'を実行した後でも' .sum() 'を使用できますか? –

+0

@RomainGonçalvès:nope。これはAR関係オブジェクトではなく配列になりました(結果的にAR関係APIもなくなりました)。しかし、集計には配列/列挙可能なメソッドを使用できます。 –

+0

申し訳ありません、ありがとう@セルジオ・チューリッセーヴ私の質問に答えると思います。おそらくDBから取得したレコードを装飾し、そのデータを操作するための砂糖を与えるライブラリがありますか?私はできるだけあなたの答えを受け入れるでしょう。 –

3

.all実際にレコードをロードしません。むしろ、それはあなたにレイジーローディングのスコープを与えます。

ActiveRecord::Calculationsは、集計などの集計を取得するためにデータベースを使用します。 Rubyの列挙可能モジュールを使用して同じ操作を行うと、ロードされたコレクションが署名に一致するsumメソッドを提供しない理由が非常に異なる結果になることがあります。

if a.loaded? 
    a.sum(&:amount) # use Enumerable#sum 
else 
    a.sum(:amount) # use ActiveRecord::Calculations#sum 
end 
1

ワンポイント覚えておくべきことは、作品をレールウェイだから

a = Invoice.all 
#=> SELECT "invoices".* FROM "invoices" 

a.sum(:amount) 
#=> SELECT SUM("invoices"."amount") FROM "invoices" 

に対し、どちらのステートメントはActiveRecordのクエリを起動しますです。あなたがお返事をArray#sum

a.map(&:amount).sum 
#=> 1234 
# OR 
a.to_a.sum(&:amount) 
#=> 1234 
+0

ブロック名やメソッド名をsumに渡すことで、マップを避けることができます。 – max

+1

次に、結果を配列に変換する必要があります。 –

関連する問題