私は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
のための仕事のように見えます エリック