Rails3: общее количество левых соединений - как рассчитать? - PullRequest
1 голос
/ 17 августа 2011

В моем приложении Пользователи регистрируются на События , которые принадлежат Потоку . Регистрации управляются в модели Registration , которая имеет логическое поле под названием « Participated ».

Я пытаюсь создать таблицу лидеров, и мне нужно знать: общее количество регистраций для каждого пользователя, а также количество регистраций пользователей в каждом отдельном потоке событий.

Я пытаюсь это (в User.rb):

# returns an array of users and their attendence count
def self.attendance_counts
    User.all( 
      :select => "users.*, sum(attended) as attendance_count", 
      :joins => 'left join `registrations` ON registrations.user_id = users.id', 
      :group => 'registrations.user_id', 
      :order => 'attendance_count DESC'
    )
end

Сгенерированный SQL работает так, чтобы просто возвращать общее количество посещений для каждого пользователя, когда я запускаю его в базе данных, но все, что возвращается, - это запись пользователя в Rails.

Я собираюсь отказаться и жестко закодировать counter_cache для каждого потока (они довольно фиксированы) в таблицу User, которая обновляется вручную каждый раз, когда атрибут Participed изменяется при сохранении модели регистрации.

Тем не менее, мне действительно любопытно, как выполнить такой запрос. Он должен появляться постоянно при расчете статистики и отчетов по записям со связями.

Ваше время и внимание очень ценится. Заранее спасибо.

1 Ответ

6 голосов
/ 17 августа 2011

Во-первых, пара моментов, касающихся стилей и функций, которые помогут вам в построении запросов к БД.

1) Вы лучше пишете это как область, а не метод, т.е.

scope attendance_counts, select("users.*, sum(attended) as attendance_count").joins(:registrations).group('registrations.user_id').order('attendance_count DESC')

2) Лучше не вызывать все / find / first для созданного вами запроса, пока он вам действительно не понадобится (т.е. в контроллере или представлении). Таким образом, если вы решите внедрить кеширование действия / фрагмента позже, запрос к БД не будет вызван, если кешированное действие / фрагмент передан пользователю.

3) В Rails есть ряд функций, помогающих собирать данные в БД. например, если вам нужен только идентификатор пользователя и сумма посещенных вами, вы можете использовать что-то вроде следующего кода:

Registrations.group(:user_id).sum(:attended)

Другие функции включают count, avg, minimum, maximum

Наконец, в ответ на ваш вопрос, rails создаст для вас атрибут для доступа к значению любых настраиваемых полей, которые есть в выбранной части вашего запроса. например,

@users = User.attendance_counts
@users[0].attendance_count # The attendance count for the first user returned by the query
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...