2012-04-27 11 views
0

Outlet.rbリファクタリングとRailsでクエリを改善

def latest_reports 
    weekly_reports.limit(10) 
end 

Outlet_controller.rb:index.slim

@all_outlets = Outlet.includes(:weekly_reports) 
@search = @all_outlets.search(params[:q]) # load all matching records 
@outlets = @search.result.order("created_at DESC").page(params[:page]) 

アウトレット/

- @outlets.each do |outlet| 
    tr 
    td= link_to outlet.name, outlet_path(outlet) 
    th 
     ul.reports 
     li class="#{'done' if outlet.monitored_today}" 
    th 
     ul.reports 
     - for report in outlet.latest_reports 
      li class="#{'done' if report.quota_met}"= report.times_monitored 

私理由はわかりませんが、これはいくつかの異なるクエリとしてそれを読み込みます。コントローラのインクルードが正しくない(モデルのメソッドを使用しているため)ので、私はかなり確信しています。

誰かがこれを改善するのを助けることができたら、私は非常に感謝しています:)。

注::私はPostgreSQLの

アップデートを開発しています完全なコントローラのアクションを投稿。あなたは

Model1.includes :model2 

を使用する場合は、レール3に

+1

あなたのモデルコードを関係 – Amar

+0

と共有することができますあなたのビューでは '@ outlet 'を使用しますが、コントローラでは' @ all_outlets'を設定します、それは何ですか? –

+0

私は宝石「ransack」を使って検索していますが、私はちょうどこれを上に更新しましたので、私が何を話しているか見ることができます。 – Ammar

答えて

2

は、少なくとも、その結果は、各モデルに1つのクエリです。結果から関連付けられたモデルのインスタンスにアクセスでき、追加のクエリは実行されません。あなたが本当に1つのクエリでそれをすべてしたい場合

、あなたはこれを行うことができます。

Model1.joins(:model2).includes(model2) 

これは、一度に両方のモデルのすべてのデータをロードし、長いJOINの素敵なクエリを生成します。 Railsは、両方のモデルのインスタンスがすでにロードされている結果を結果として取り込みます。

だから、あなたは

@all_outlets = Outlet.includes(:weekly_reports).joins(:weekly_reports) 

@all_outlets = Outlet.includes(:weekly_reports) 

置き換えることができるはずですし、それが1つのクエリにすべてを組み合わせる必要があります。

+0

私のコントローラで上記のように、weekly_reportsテーブルでJOINにインクルードを使用しています。しかし、1つのクエリだけでコンセントを取得し、それに関連付けられた最後の10件のweekly_reportを取得したい。 – Ammar

関連する問題