SQL generovaný výrazem není platný dotaz, seskupujete ho podle user_id
a na základě toho vybrat spoustu dalších polí, ale neříkat DB, jak by měla agregovat ostatní pole. Pokud například vaše data vypadají takto:
a | b
---|---
1 | 1
1 | 2
2 | 3
Nyní, když požádáte db o seskupení podle a
a také vrátí b, neví, jak agregovat hodnoty 1,2
. Musíte říct, jestli je potřeba vybrat min, max, průměr, součet nebo něco jiného. Právě když jsem psal odpověď, objevily se dvě odpovědi, které by to všechno mohly lépe vysvětlit.
Ve vašem případě použití si však myslím, že nechcete skupinu na úrovni db. Protože existuje pouze 10 umění, můžete je seskupit ve své aplikaci. Tuto metodu však nepoužívejte u tisíců umění:
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],
# ....
# }
UPRAVIT: Vyberte nejnovější_umění, ale pouze jedno umění na uživatele
Jen pro představu sql (netestoval jsem to, protože na svém systému nemám nainstalovaný 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
Toto řešení je založeno na praktickém předpokladu, že žádná dvě umění pro stejného uživatele nemohou mít stejnou nejvyšší created_at, ale může být špatně, pokud importujete nebo programově vytváříte velké množství umění. Pokud předpoklad neplatí, může být sql více vymyšlený.
UPRAVIT: Pokuste se změnit dotaz na 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])