ruby-on-rails - 我认为这个查询是错误的吗?

标签 ruby-on-rails activerecord rails-activerecord

我的关联(简化):

项目

has_many :users
has_many :tasklists

任务列表

has_many :tasks

任务

belongs_to :tasklist

用户

has_many :assigned_tasks, class_name: 'Task', foreign_key: 'assignee_id'

我想做什么

我想显示一个项目资源,其中包含项目的用户,每个用户都包含分配给他们的任务。

我尝试过:

project = Project.includes(users: :assigned_tasks).find(params[:id])

这种方法有效,只是它甚至返回不属于父项目的分配任务。这不是我想要的。我只想要属于该项目子级的已分配任务。

也许整个方法都不正确。也许我应该首先考虑任务,例如:

project = Project.includes(tasklists: :tasks)

但是我该如何按用户组织任务呢?

我希望我说得有道理。任何帮助将不胜感激。 谢谢

最佳答案

解决此问题的方法有很多种,具体取决于您的优先级。让我们首先查看您的第一个查询:

project = Project.includes(users: :assigned_tasks).find(params[:id])

这样做的优点是您只需执行一次数据库查询即可取回所有信息,缺点是您将取回所有分配的任务,而不仅仅是此任务的任务项目。但您始终可以在显示任务时对其进行过滤:

project.users.each do |user|
  user.assigned_tasks.select {|t| t.project_id == project.id}.each do |task|
    puts task
  end
end

或者,您可以首先检索项目及其用户:

project = Project.includes(:users).find(params[:id])

add a scope到您的任务 a where clause on the join仅查找该项目的任务:

class Task < ActiveRecord::Base
  belongs_to :tasklist
  scope :for_project, -> (project) {joins(:tasklist).where(tasklist: {project: project})} 
end

然后您可以在显示任务时使用此范围:

project.users.each do |user|
  user.assigned_tasks.for_project(project).each do |task|
    puts task
  end
end

这样做的缺点是您可能会遇到 N+1 queries problem 。这也不是清晰度方面的重大进步。


也许最好的方法是允许从 project 对象直接访问项目的任务:

class Project < ActiveRecord::Base
  has_many :users
  has_many :tasklists
  has_many :tasks, through: :tasklists
end

class Task < ActiveRecord::Base
  belongs_to :tasklist
  has_one :project, through: :tasklist
end

它允许您通过project.tasks访问项目的任务。协会是 Enumerable ,所以您可以使用 group_by就像处理任何数组一样:

project.tasks.group_by(&:user).each do |user, tasks]
  puts user.name
  tasks.each do |t|
    puts t
  end
end

为了保持较低的数据库查询数量,您可以将任务加载到项目中:

project = Project.includes(:users, :tasks).find(params[:id])

关于ruby-on-rails - 我认为这个查询是错误的吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27940366/

相关文章:

ruby-on-rails - 如何合并两个 activerecord 查询?

ruby-on-rails - 未设置默认 bool 值 Rails 4 Postgres

ruby-on-rails - Rails 控制台显示所有型号

ruby-on-rails - 使用 sudo 设置 Ruby on Rails 是否被认为是一种不好的做法?

ruby-on-rails - Rails 3. 获取相关模型的属性

ruby-on-rails - Rails/ActiveRecord : field normalization

ruby-on-rails-3 - Rails 休息服务 GET

ruby-on-rails - 为什么在保存对象后使用 'reload' 方法? (Hartl Rails Tut 6.30)

mysql - 查询两个用户之间的公共(public)组

postgresql - 按关联查询和对模型的影响