В Rails - Как иметь один запрос, который имеет несколько запросов? - PullRequest
2 голосов
/ 05 февраля 2011

In имеют 3 модели здесь:

  • проекты
  • потоков (project_id)
  • thread_participations (thread_id, читать логическое значение)

Прямо сейчас у меня есть список проектов пользователя, и этот список показывает, сколько потоков не прочитано в каждом проекте.Огромная проблема заключается в том, что если у пользователя есть несколько проектов (что делают все пользователи), это приводит к тому, что БД получает несколько запросов, по одному на проект.

Я бы хотел использовать Rails для построения запроса,что с одним попаданием в БД возвращает счетчик непрочитанных для каждого проекта пользователя.

Вот что я использую сегодня в представлении:

<% @projects.each_with_index do |project, i| %>
<%=project %>: <%= Thread.unread(current_user,project).count %>
<% end %>

И в потоке Модель:

  scope :unread, lambda { |user,project| 
      includes(:project,:thread_participations).where(:project_id => project.id, :thread_participations => {:read => false, :user_id => user.id})
  }

Есть предложения, как это сделать?Кроме того, в какой модели это должно жить?Может быть, модель пользователя, поскольку она не зависит от проекта или потока?

Спасибо

1 Ответ

1 голос
/ 05 февраля 2011

Есть несколько способов структурировать этот запрос, но вот один.

Вы можете выполнить это в одном запросе, а затем просмотреть результаты. Сначала я бы создал область для участия в потоках для непрочитанных для определенного пользователя. Затем используйте область действия и включите все потоки и проекты, сгруппируйте их по идентификатору проекта (чтобы вы получили непрочитанные потоки для этого проекта), а затем подсчитайте количество непрочитанных потоков, посчитав threads.id:

class ThreadParticipations
  scope :unread, lambda{ |user| where(user_id: user.id, read: false) }
end

ThreadParticipations
  .unread(current_user)
  .includes(:thread => :project)
  .group('projects.id')
  .count('threads.id')

=> { 10 => 15, 11 => 10 }
# project(10) has 15 unread threads and project(11) has 10 unread threads
...