gpt4 book ai didi

sql - 轨道 5.1 (postgresql) : efficient DB query to select parent records and filtered children records

转载 作者:行者123 更新时间:2023-11-29 13:45:32 30 4
gpt4 key购买 nike

我正在开发一个任务管理系统,其中一个项目有很多任务,一个任务可以分配给用户

我想添加一个“我的任务”页面,显示所有项目以及当前用户的任务。

像这样,每个任务都分配给 current_user

Project #1
- task 1
- task 2
Project #2
- task 1
- task 2
Project #3
- task 1
- task 2
- task 3

我试图用伪 ActiveRecord 代码实现的目标:

@projects_with_tasks = current_user.projects.includes(:tasks).where(tasks: { user_id: current_user.id })

然后我想遍历每个项目,列出分配给 current_user 的任务:

<% @projects.each do |project| %>
<%= project.title %>
<ul>
<% project.tasks.each do |task| %>
<li><%= task.title %> - <%= task.due_date %></li>
<% end %>
</ul>
<% end %>

这看起来很简单,但是当我调用 project.tasks 时,它会返回并加载项目的所有任务,而不仅仅是当前用户的任务。

有没有一种方法可以高效地获取项目和过滤后的任务列表?

我目前拥有的最佳解决方案是首先获取所有项目,然后遍历它们并进行单独的数据库查询以检索所有已过滤的任务。但是,如果某人有 20 个以上的项目参与(可能在我的用例中),那么就是 21 个以上的查询(1 个用于所有项目,然后 1 个用于任务)。不要介意某些用户将拥有 50 个项目的情况......

我更喜欢将所有内容都保存在 ActiveRecord 中,但我也知道这可能是创建一个带有一些 SQL 的查询对象的情况。

最佳答案

如果你的模型是这样定义的:

# app/models/user.rb
class User < ActiveRecord::Base
has_many :tasks
end

# app/models/task.rb
class Task < ActiveRecord::Base
belongs_to :project
belongs_to :user
end

# app/models/project.rb
class Project < ActiveRecord::Base
has_many :tasks
end

您可以使用此查询查询具有过滤任务的项目:

@projects = Project.includes(:tasks).joins(:tasks).where(Task.table_name => { user_id: current_user.id })

.includes(:tasks) - 急切加载任务

.joins(:tasks) - 执行 INNER JOIN 而不是 LEFT OUTER JOIN

.where(Task.table_name => { user_id: current_user.id }) - 按用户过滤任务

您还可以将范围添加到您的 Task 模型:

scope :for_user, ->(user) { where(user: user) }

之后,查询可以这样写:

@projects = Project.includes(:tasks).joins(:tasks).merge(Task.for_user(current_user))

输出将是相同的。

注意:

我猜你不会这样做,但仍然值得一提的是,你应该避免在迭代加载了上述任何查询的项目时调用 project.tasks.reload。它将强制重新加载 tasks 关联而不被用户过滤。

关于sql - 轨道 5.1 (postgresql) : efficient DB query to select parent records and filtered children records,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48937319/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com