2009-08-14 3 views
2

У меня есть 3 таблицы - места, пользователи и обновления (у которых есть целое число для оценки) - и я хочу написать запрос, который вернет список всех моих мест, а также их средние оценки используя только последнее обновление для каждого человека, место встречи. Например, если пользователь 1 оценивает место проведения A один раз в 9 утра с 4, а затем оценивает его снова в 17:00 с 3, я хочу использовать рейтинг 3, поскольку он более поздний. Существуют также некоторые необязательные условия, например, как последние обновления должны быть, и если есть массив идентификаторов пользователей, пользователи должны находиться внутри.Сложные запросы в 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 является нулевым» состоянием, потому что я все еще хочу, чтобы места вернулись даже если у них нет связанных с ними обновлений.

Спасибо, Эрик

ответ

1

Хлоп, что выглядит как работа для find_by_sql мне. Когда вы делаете что-то такое сложное, я считаю, что лучше отказаться от работы с ActiveRecord и DIY.

Смежные вопросы