2010-12-27 12 views
1

Ich versuche, diese Abfrage in Arel zu bauen:eine Unterabfrage mit Arel in Rails3 Gebäude

SELECT FLOOR(AVG(num)) FROM (
SELECT COUNT(attendees.id) AS num, meetings.club_id FROM `meetings` INNER JOIN `attendees` ON `attendees`.`meeting_id` = `meetings`.`id` WHERE (`meetings`.club_id = 1) GROUP BY meetings.id) tmp 
GROUP BY tmp.club_id 

Es gibt die durchschnittliche Anzahl der Teilnehmer pro Sitzung pro Club. (Ein Club hat viele Sitzungen und ein Treffen hat viele Teilnehmer)

Bisher habe ich (deklariert in der Klasse-Club < Activerecord :: Base):

num_attendees = meetings.select("COUNT(attendees.id) AS num").joins(:attendees).group('meetings.id') 
Arel::Table.new('tmp', self.class.arel_engine).from(num_attendees).project('FLOOR(AVG(num))').group('tmp.club_id').to_sql 

aber, erhalte ich die Fehlermeldung:

undefined method `visit_ActiveRecord_Relation' for #<Arel::Visitors::MySQL:0x9b42180> 

Die Dokumentation zum Generieren von nicht trivialen ARel-Abfragen ist ein bisschen schwer zu bekommen. Ich habe verwendet http://rdoc.info/github/rails/arel/master/frames Bin ich das falsch nähern? Oder bin ich ein paar Methoden weg von einer Lösung?

Antwort

1

Dies ist, wie ich es ohne die Verwendung von Arel Methoden erreicht:

sql = 'SELECT FLOOR(AVG(num)) AS avg FROM (' 
sql << meetings.select("COUNT(attendees.id) AS num, meetings.club_id").joins(:attendees).group('meetings.id').to_sql 
sql << ') AS tmp GROUP BY tmp.club_id' 
connection.select_value(sql, 'avg').to_i 
3

Wenn Sie conplicated bauen, vollständige Abfragen in Arel, gibt es keine Möglichkeit, dass in eine Liste der richtigen Active Objekte zu drehen. Nur die Prädikate in Arel, die Dinge, die Sie in einer .where() - Funktion angeben können, können verwendet werden.

Diese Vorteile werden jedoch kurz und bündig in die meta_where gem verpackt:

http://metautonomo.us/projects/metawhere/ 

ihre Ratschläge Nehmen Sie über das Hinzufügen von

MetaWhere.operator_overload! 

zu Ihrem

config/initializers/meta_where.rb 

, so dass Sie Machen Sie Dinge mit der Funktion '[]', die dem Symbol hinzugefügt wird:

Attendee.select(:count[:id].as('person_count')).group(:id) 
+0

MetaWhere war für Squeel veraltet, und Squeel wird jetzt ersatzlos veraltet. Eine weniger invasive und aktuell unterstützte Lösung sind Ariel-Helfer: https://github.com/camertron/arel-helpers – Peeja