2010-12-20 10 views
0

アクティビティに記録されている習慣がない現在の月の日数をカウントする、month_days_not_practicedと呼ばれる多くのPracticesを持つアクティビティモデルのメソッドを作成したい(注:days_in_monthはヘルパーメソッドです):Railsのwhere条件に一致するセットの最初のレコードを取得する

def month_days_not_practiced(date = Date.today) 
    p = practices.where(:created_at => date.at_beginning_of_month..date.at_end_of_month).count 
    days_in_month - p 
    end 

ただし、月に1つのレコードしか返しません。

私のカスタムSQLを手伝ってくれる人がいますか?私は現時点で空白を描いています。

TIA!

アンディ

答えて

1

クエリの最後にこれを置く:

.group("DATE(created_at)") 
+0

これは "OrderedHashを強制的にFixnumエラーにすることはできないので、結果のハッシュを配列に変換しました:.group(" DATE(created_at) ")。to_a.countそしてそれは正常に動作しました –

0

あなたが簡単なGROUP BY操作でこれを行うとしたいレコードを取得することができますが、あなたは、これは特に効率的ではないかもしれませんこれはサーバ側のソートを必要とし、インデックスできないためです。

SELECT DATE(created_at) AS on_date, COUNT(id) AS count_for_date FROM practices GROUP BY DATE(created_at) 

これは、1日にインデックス登録されたエントリの数を返します。これらはグループ化されないため、ゼロのエントリはありませんが、あなたが観察したように、存在する必要がある数に基づいて失われた日数をいつでも計算できます。

あなたは、接続オブジェクトを使用して、これらの結果を反復処理することができます。これを最適化する

Practice.connection.select_rows("...").each do |date, count| 
    # ... 
end 

方法は、単にあなたのスキーマ内のインデックス付きの日付列を追加することです:

add_column :practices, :created_on, :date 

execute "UPDATE practices SET created_on=created_at" 

add_index :practices, :created_on 

は割り当てるようにしてくださいモデルを保存するときにこのフィールドに入力してください:

class Practice < ActiveRecord::Base 
    before_create :assign_created_on 

protected 
    def assign_created_on 
    self.created_on = Date.today 
    end 
end 

完全にインデックス可能で、はるかに高速です。

+0

なぜ –

+0

少しの微調整(コメントを参照)で私のニーズに十分であったライアンの答えは、あなたの答えがスピードを上げるが、今は必要な合併症ではないと確信しています。 、andy –

関連する問題