【问题标题】:In Rails - How to have one query that has multiple queries?在 Rails 中 - 如何让一个查询有多个查询?
【发布时间】:2011-02-05 18:01:55
【问题描述】:

这里有 3 个模型:

  • 项目
  • 线程(project_id)
  • thread_participations(thread_id,读取布尔值)

现在我有一个用户项目的列表,该列表显示每个项目有多少线程未读。这里最大的问题是,如果用户有多个项目(所有用户都这样做),则会导致数据库受到多个查询的影响,每个项目一个。

我想使用 Rails 构建一个查询,该查询通过一次 DB 命中,返回每个用户项目的未读计数。

这是我今天在视图中使用的:

<% @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})
  }

关于如何做到这一点的任何建议?这应该住在哪个模型中?也许是用户的模型,因为它不是特定于项目或线程的?

谢谢

【问题讨论】:

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


    【解决方案1】:

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

    您可以在单个查询中执行此操作,然后循环遍历结果。我将首先为某个用户的未读线程创建一个范围。然后使用范围并包括所有线程和项目,按项目 id 分组(以便您获得该项目的未读线程),然后通过计算 threads.id 来计算未读线程的数量:

    线程参与类 范围:未读,lambda{ |用户|其中(user_id:user.id,读取:false)} 结尾 主题参与 .未读(当前用户) .includes(:thread => :project) .group('projects.id') .count('threads.id') => { 10 => 15, 11 => 10 } # project(10) 有 15 个未读线程,project(11) 有 10 个未读线程

    【讨论】:

    • 谢谢,我不确定我是否 100% 关注,所以让我问一下……为什么 ThreadParticipations 中有未读范围,而不是像我现在这样的 Thread?只是好奇。此外,第二个块(ThreadParticipations .unread(current_user...) 生活在哪里?控制器?谢谢
    • 还有一点,未读范围不是按project_id过滤的吗?
    • 您不按 project_id 过滤的原因是您希望在查询中包含所有用户的项目。如果您按 project_id 过滤,那么您将回到原来的问题,即必须执行多个查询(每个项目一个)。
    • 您必须自己进行一些调查才能进一步了解您的具体情况。此查询有许多变体,但核心概念是相同的:包括您想要的表,按您要关联的属性分组,然后计数。我的解决方案应该为您提供执行单个计数查询的基础知识,而不是为每个项目提供一个。据我所知,您无法获得与用户相关但没有线程的项目,因为您的原始帖子中没有任何内容表明您如何将用户与没有线程的项目相关联。
    • 如果您想要该用户尚未阅读的项目,您可以使用您的数组在单个查询中获取所有项目: Project.find([[1,1],[2, 3],[5,1]].map{ |k| k[0] })。您还可以使用用户项目列表来填充未读计数,方法是引用此数组并在每个项目上填写相关项目 ID 的 unread_count 变量。如何使用数组取决于您,但如果您想显示除 id 和 unread_count 之外的其他项目信息,则必须对数组进行一些额外的处理以使其成为您想要的格式。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-18
    • 1970-01-01
    相关资源
    最近更新 更多