2011-01-03 8 views
0

Ich verwende Rails 3 und postgresql. Ich habe folgende Genres: Rock, Ambiente, Alternative, House.Wie erhalten Sie aktive Genres in ActiveRecord?

Ich habe auch zwei Benutzer registriert. Man hat Rock und die anderen Haus, wie ihre Genres. Ich muss Rock- und House-Genre-Objekte zurückgeben.

Ich habe zwei Möglichkeiten gefunden, dies zu tun. Man verwendet Gruppe:

Genre.group('genres.id, genres.name, genres.cached_slug, genres.created_at, genres.updated_at').joins(:user).all 

Und das andere mit DISTINCT:

Genre.select('DISTINCT(genres.name), genres.cached_slug').joins(:user) 

beide die gleichen gewünschten Ergebnisse zurück. Aber welches ist besser leistungsfähig? Mit Gruppe() sieht chaotisch, da ich alle Felder in der Genre-Tabelle, um anzuzeigen, haben sonst werde ich Fehler als solche erhalten:

ActiveRecord::StatementInvalid: PGError: ERROR: column "genres.id" must appear in the GROUP BY clause or be used in an aggregate function 
: SELECT genres.id FROM "genres" INNER JOIN "users" ON "users"."genre_id" = "genres"."id" GROUP BY genres.name 

Antwort

1

A DISTINCT und GROUP BY in der Regel die gleiche Abfrageplan erzeugen, so sollte die Leistung sein, die Dasselbe gilt für beide Abfragekonstrukte.

Da Sie keine Aggregatfunktionen verwenden, sollten Sie die eine, die am meisten Sinn in Ihrer Situation macht, was ich glaube, ist dieses:

Genre.select('DISTINCT(genres.name), genres.cached_slug').joins(:user) 

Dieses klarer sein wird, wenn sie versuchen zu lies deinen Code später und erinnere dich daran, was du hier gemacht hast und, wie du angemerkt hast, ist viel weniger chaotisch.

aktualisieren

Es hängt von der Version von Postgresql Sie verwenden. Die Verwendung der Versionen < 8.4, GROUP BY ist schneller. Ab Version 8.4 sind sie identisch.

+0

Gereinigt mehr mit: Genre.select ('DISTINCT (genres.name), genres. *'). Joins (: user) –

Verwandte Themen