2009-08-14 2 views
2

장소, 사용자 및 업데이트 (정격에 정수가있는 테이블)가 3 개 있습니다. 모든 평균값뿐만 아니라 모든 장소의 목록을 반환하는 쿼리를 작성하고 싶습니다. 각 사람, 장소 쌍에 대한 최신 업데이트 만 사용합니다. 예를 들어, 사용자 1이 오전 9시에 한 번 4시를 사용하여 장소 A를 평가 한 다음 3시를 사용하여 오후 5시에 다시 평가하면 3 일 때만 등급을 사용하려고합니다. 또한 업데이트가 얼마나 최근 버전인지와 사용자가 속해야하는 사용자 ID 배열이있는 경우와 같은 선택적 조건이 있습니다.복잡한 쿼리를 레일에 입력하십시오.

누구나 이와 같은 것을 작성하는 가장 좋은 방법은 깨끗하고 효율적이라는 제안이 있습니까? 나는 트릭을 할해야 다음 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에서 그 일을 멀리하는 것이 가장 좋습니다.

관련 문제