在Rails中 - 如何让一个查询具有多个查询?

时间:2011-02-05 18:01:56

标签: ruby-on-rails ruby-on-rails-3 activerecord activemodel

这里有3个型号:

  • 项目
  • threads(project_id)
  • thread_participations(thread_id,read boolean)

现在我有一个用户项目列表,列表显示每个项目未读取的线程数。这里的一个巨大问题是,如果用户有多个项目(所有用户都这样做),它会导致DB被多个查询命中,每个项目一个。

我想使用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 个答案:

答案 0 :(得分:1)

有几种方法可以构建此查询,但这里有一个。

您可以在单个查询中执行此操作,然后循环结果。我首先要为特定用户的未读线程参与创建一个范围。然后使用范围并包括所有线程和项目,按项目ID分组(这样你就可以获得该项目的未读线程),然后通过计算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