J'ai 3 tables - sites, utilisateurs, et mises à jour (qui ont un nombre entier pour l'évaluation) - et je veux écrire une requête qui renverra une liste de tous mes lieux ainsi que leurs estimations moyennes en utilisant seulement la mise à jour la plus récente pour chaque personne, paire de sites. Par exemple, si l'utilisateur 1 évalue le lieu A une fois à 9 heures avec un 4, puis le réévalue à 17 heures avec un 3, je veux seulement utiliser la note 3, car c'est plus récent. Il existe également des conditions facultatives, telles que la date à laquelle les mises à jour doivent être récentes et s'il existe un tableau d'ID utilisateur dans lequel les utilisateurs doivent se trouver.Complexe Rejoindre des requêtes dans Rails
Quelqu'un a-t-il une suggestion sur la meilleure façon d'écrire quelque chose comme ça pour qu'il soit propre et efficace? Je l'ai écrit la named_scope suivante qui devrait faire l'affaire, mais il est assez laid:
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
}
}
}
I comprennent le dernier « updates.id est nulle » condition parce que je veux toujours les lieux retournés même s'ils n'ont aucune mise à jour associée à eux.
Merci, Eric