De sql die door de expressie wordt gegenereerd, is geen geldige zoekopdracht, u groepeert op user_id
en het selecteren van veel andere velden op basis daarvan, maar niet de DB vertellen hoe het de andere bestanden moet samenvoegen. Als uw gegevens er bijvoorbeeld zo uitzien:
a | b
---|---
1 | 1
1 | 2
2 | 3
Als je db nu vraagt om te groeperen op a
en geeft ook b terug, het weet niet hoe de waarden 1,2
. moeten worden geaggregeerd . U moet aangeven of het min, max, gemiddelde, som of iets anders moet selecteren. Net toen ik het antwoord aan het schrijven was, waren er twee antwoorden die dit allemaal beter zouden kunnen verklaren.
In jouw geval denk ik echter dat je geen group by op db-niveau wilt. Aangezien er slechts 10 kunsten zijn, kunt u ze groeperen in uw toepassing. Gebruik deze methode echter niet met duizenden kunsten:
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],
# ....
# }
BEWERK: Selecteer nieuwste_arts, maar slechts één kunst per gebruiker
Om je een idee te geven van sql (heb het niet getest omdat ik geen RDBMS op mijn systeem heb geïnstalleerd)
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
Deze oplossing is gebaseerd op de praktische aanname dat geen twee kunsten voor dezelfde gebruiker dezelfde hoogste create_at kunnen hebben, maar het kan wel eens verkeerd zijn als je een groot deel van de kunst importeert of programmatisch maakt. Als de aanname niet klopt, kan de sql meer gekunsteld worden.
BEWERKEN: Poging om de zoekopdracht te wijzigen in 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])