2011-01-13 18 views
2

以下のクエリがありますが、これはDRYではないと確信しています。しかし、私は、各varについて再度問い合わせるのではなく、取引varをトラフする方法を見つけることができません。出来ますか?トラフの検索結果を検索して多くのリクエストを作成しないようにするにはどうすればいいですか

deals = Deal.all 
won = Deal.find(:all, :conditions => ["status = 'won'"]).count 
pending = Deal.find(:all, :conditions => ["status = 'pending'"]).count 
lost = Deal.find(:all, :conditions => ["status = 'lost'"]).count 

答えて

5

使用GROUP BY SQL句:

Hash[Deal.all(:select => 'status, count(*) as count', :group => 'status').map{|e| 
    [e.status, e.count] 
}] 

編集:私はすでに、すべてのレコードがロードされていることを忘れてしまいました。その場合、あなたは状況ごとのカウントをこのように得ることができます。

Hash[deals.group_by(&:status).map{|k,v| [k,v.count]}] 
+0

この1つは美しいです!可能な改善のために私が思い付くことができるのは、すでに定義されたvar取引を使用できるかどうかだけです。 (いい考え方もここにあります。この種の解決策を見てもらえます:-)) –

+1

あなたはそうです、私はその部分を逃しました。私は答えを編集しました。 –

+0

美しい!魅力的な作品!どうもありがとう! –

0

私はあなたがこのためにRubyの注入機能を使用することができると思う:あなたのディールのオブジェクトは、典型的には、ActiveRecordのオブジェクト(ある場合

won = deals.inject(0) {|total, deal| deal.status == 'won' ? total + 1 : total } 
+1

私はこの種の解決法について考えましたが、これは良い考えではないと思いますが、基本的にcount()を再定義します。 –

+0

良い点。データベースがカウントを処理させることは、おそらくもっと効率的です。 – Roy

+0

私は彼が 'Array#count'を参照していたと信じています:' deals.count {| deal | deal.status == 'won'} '。 –

0

モデル用ケース)は、データベースに、カウントを起動することができます。それを行うための別の方法は、そのSQLクエリを記述することです

won = Deal.count_by_sql("select count(*) from deals where status = 'won'")

count_by_status = Deal.find_by_sql("select status,count(*) from deals group by status;")

その後、あなたは(私が思うハッシュの配列となります)の結果を使用することができますすべてのあなたのためのカウント、および状況によってグループ化を行うだろう。

1

次使用することができます: -

Deal.find(:すべて、: '状態deal_countとして)ID(カウント' =>を選択し、:グループ=> '状態')

1

することができますArray#select

deals = Deal.all 
won = deals.select { |deal| deal.status == 'won' }.length 
# similar for pending and lost 
+0

うん、それはまさに私が探していたものです。 MladenJablanovićの答えはより柔軟ですが、このソリューションよりもI/Oを増やさなければならない余分なdbコールが必要です。あなたはどの取引ステータスがあるか分かっている限り、これは良いです。 –

関連する問題