2010-12-27 1 views
1

Я пытаюсь построить этот запрос в AREL:Построение подзапроса с AREL в Rails3

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 

возвращает среднее число посетителей за встречу, за клуб. (Клуб имеет много встреч и встреча имеет много участников)

До сих пор я (объявленный в классе 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 

, но я получаю ошибку:

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

Документация для генерации нетривиальных запросов ARel немного затруднительна. Я использую http://rdoc.info/github/rails/arel/master/frames. Я неправильно подхожу? Или я несколько методов от решения?

ответ

1

Это, как я достиг его без использования методов AREL:

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

Когда вы строите conplicated, полные запросы в Arel, нет никакого способа, чтобы превратить это в список соответствующих объектов ActiveRecord. Можно использовать только предикаты в Ареле, то, что вы можете указать внутри функции .where().

Эти преимущества, однако, лаконично завернутые в meta_where драгоценный камень:

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

Возьмите их советы о добавлении

MetaWhere.operator_overload! 

к вашему

config/initializers/meta_where.rb 

, так что вы можете делать вещи с добавленной функцией «[]» к символу:

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

MetaWhere устарела для Squeel, а Squeel теперь устарела без замены. Менее инвазивным и в настоящее время поддерживается решение isl-helpers: https://github.com/camertron/arel-helpers – Peeja