1

レール2.3.4

私はグーグルを検索しましたが、私のジレンマに対する答えが見つかりませんでした。

この議論のために、私は2つのモデルを持っています。ユーザーとエントリ。ユーザーは多くのエントリを持つことができます(毎日1つ)。

エントリには値とsent_at日付があります。

BY DAYOFWEEKのユーザーのエントリの平均値を照会して表示したいと思います。したがって、ユーザーが過去3週間の値を入力した場合、日曜日、月曜日などの平均値を表示したいと思います。MySQLでは、次のようになります。

SELECT DAYOFWEEK(sent_at) as day, AVG(value) as average FROM entries WHERE user_id = ? GROUP BY 1

そのクエリは、ユーザーが少なくとも1つのエントリを持っていた日数に応じて、0〜7個のレコードを返します。

find_by_sqlを見ましたが、Entryを検索しているときに、Entryオブジェクトを返したくありません。代わりに、最大7日と平均の配列が必要です...

また、ユーザーがログインしたときにこれをユーザーモデルにロードして、ダッシュボードに表示できるようにするため、このパフォーマンスについて少し心配しています。任意のアドバイス/ポインタを歓迎します。私はRailsに比較的慣れていません。

4

2 に答える 2

2

データベースを直接クエリできます。実際のActiveRecordオブジェクトを使用する必要はありません。例えば:

ActiveRecord :: Base.connection.execute "SELECT DAYOFWEEK(sent_at)as day、AVG(value)as average FROM items WHERE user_id =#{user.id} GROUP BY DAYOFWEEK(sent_at);"

これにより、MySql::ResultまたはMySql2::Resultが得られ、この列挙型でそれぞれまたはすべてを使用して、結果を表示できます。

キャッシングに関しては、memcachedを使用することをお勧めしますが、他のRailsキャッシング戦略でも同様に機能します。memcachedの優れた利点は、一定時間後にキャッシュを期限切れにすることができることです。例えば:

結果=Rails.cache.fetch('user /#{user.id} / averages'、:expires_in => 1.day)do
  #SQLクエリと結果はここに表示されます
終わり

これにより、結果が「user//averages」キーの下で1日memcachedに入れられます。たとえば、IDが10のユーザーの場合、平均は「user / 10 / average」の下のmemcachedにあり、次にこのクエリを実行するときに(同じ日以内に)、実際にヒットする代わりに、キャッシュされたバージョンが使用されます。データベース。

于 2011-02-03T05:54:24.787 に答える
0

テストされていませんが、次のようなものが機能するはずです。

@user.entries.select('DAYOFWEEK(sent_at) as day, AVG(value) as average').group('1').all

select列を明示的に指定するために使用する場合、返されるオブジェクトは読み取り専用です。Railsは、変更できる列と変更できない列を確実に判別できません。この場合、選択した列を変更しようとはしないでしょうが、結果のオブジェクトを介してsent_atまたは列を変更することもできます。value

ここで起こっていることの内訳については、 ActiveRecordクエリガイドをかなり新しい形式で確認してください。ああ、そのクエリが機能しない場合は、投稿してください。これに遭遇する可能性のある他の人がそれを見ることができます(そして私はおそらく更新できます)。


配列を返すため、これは機能しないため、代わりに次entriesを使用してみてください。join

User.where(:user_id => params[:id]).joins(:entries).select('...').group('1').all

繰り返しますが、これが機能するかどうかはわかりません。where通常は後に指定できますが、そこに結合されているのjoinsは見たことがありません。selectここで注意が必要なのselectは、おそらく、に関するデータuserをまったく返さないようにすることです。(docs )を使用してクエリを呼び出し、関連付けマッピングをスキップfind_by_*するメソッドをモデルに記述することを優先して、メソッドを回避する方が理にかなっている場合があります。Entryselect_all

于 2011-02-03T05:49:45.747 に答える