2009-08-14 10 views
2

私は3つのテーブル(会場、ユーザー、および更新(定格のための整数)を持っています)を持っています - そして、私はすべての会場のリストとそれらの平均評価を返す各個人、会場のペアについて最新の更新のみを使用します。たとえば、ユーザー1が9時に会場Aに4を付けて料金を請求し、さらに3時に午後5時に評価した場合、最近の評価である3の評価を使用したいだけです。また、いくつかのオプション条件があります。例えば、アップデートの最新の状態、ユーザーIDの配列がある場合などです。複雑なJoin Railsでのクエリ

誰かが、このようなものを書くための最良の方法が、きれいで効率的なものであることについて何か提案していますか?私はトリックを行う必要があり、次のnamed_scopeを書かれているが、かなり醜いです:

named_scope :with_avg_ratings, lambda { |*params| 
hash = params.first || {} 
has_params = hash[:user_ids] || hash[:time_ago] 
dir = hash[:dir] || 'DESC' 
{ 
    :joins => %Q{ 
    LEFT JOIN (select user_id, venue_id, max(updated_at) as last_updated_at from updates 
    WHERE type = 'Review' GROUP BY user_id, venue_id) lu ON lu.venue_id = venues.id 
    LEFT JOIN updates ON lu.last_updated_at = updates.updated_at 
    AND updates.venue_id = venues.id AND updates.user_id = lu.user_id 
    }, 
    :select => "venues.*, ifnull(avg(rating),0) as avg_rating", 
    :group => "venues.id", 
    :order => "avg_rating #{dir}", 
    :conditions => Condition.block { |c| 
    c.or { |a| 
     a.and "updates.user_id", hash[:user_ids] if hash[:user_ids] 
     a.and "updates.updated_at", '>', hash[:time_ago] if hash[:time_ago] 
    } if has_params 
    c.or "updates.id", 'is', nil if has_params 
    } 

} 

}

は私がまだ会場にも返さたいので、最後の条件「updates.idがnull」が含まそれらに関連付けられた更新がない場合

おかげで、私にfind_by_sqlのための仕事のように見えます エリック

答えて

1

む〜、。あなたが複雑なことをやっているとき、私はActiveRecordとDIYから離れて仕事をするのが最善だと思っています。