Sql, генериран от израза, не е валидна заявка, вие групирате по user_id
и избиране на много други полета въз основа на това, но без да казва на DB как трябва да агрегира другите файлове. Например, ако вашите данни изглеждат така:
a | b
---|---
1 | 1
1 | 2
2 | 3
Сега, когато поискате от db да групира по a
и също връща b, то не знае как да агрегира стойности 1,2
. Трябва да кажете дали трябва да изберете мин., макс., средно, сума или нещо друго. Точно докато пишех отговора, имаше два отговора, които биха могли да обяснят всичко това по-добре.
Във вашия случай на употреба обаче мисля, че не искате група от на ниво db. Тъй като има само 10 изкуства, можете да ги групирате във вашето приложение. Все пак не използвайте този метод с хиляди изкуства:
arts = Art.all(:order => "created_at desc", :limit => 10)
grouped_arts = arts.group_by {|art| art.user_id}
# now you have a hash with following structure in grouped_arts
# {
# user_id1 => [art1, art4],
# user_id2 => [art3],
# user_id3 => [art5],
# ....
# }
РЕДАКТИРАНЕ: Изберете latest_arts, но само едно изкуство на потребител
Само за да ви дам представа за sql (не съм го тествал, тъй като нямам RDBMS инсталиран на моята система)
SELECT arts.* FROM arts
WHERE (arts.user_id, arts.created_at) IN
(SELECT user_id, MAX(created_at) FROM arts
GROUP BY user_id
ORDER BY MAX(created_at) DESC
LIMIT 10)
ORDER BY created_at DESC
LIMIT 10
Това решение се основава на практическото предположение, че няма две изкуства за един и същ потребител, които могат да имат една и съща най-висока created_at, но може да е погрешно, ако импортирате или програмно създавате голяма част от изкуства. Ако предположението не е вярно, sql може да стане по-измислен.
РЕДАКТИРАНЕ: Опитайте се да промените заявката на Arel:
Art.where("(arts.user_id, arts.created_at) IN
(SELECT user_id, MAX(created_at) FROM arts
GROUP BY user_id
ORDER BY MAX(created_at) DESC
LIMIT 10)").
order("created_at DESC").
page(params[:page]).
per(params[:per])