当 JOINS 涉及超过 2 个表时,如何处理 Ruby on Rails 中的关联?

问题描述 投票:0回答:1

我正在开发 Ruby on Rails 服务器(v6.0.1),并且当连接涉及三个表时,我正在寻找更清晰的 ActiveRecord 连接。这是正在考虑的五个模型的准系统复制品,以解释这种情况。

class Person
  # represents a person
end

class Company
  # represents a business entity
  has_many :shifts
end

class Employee
  # represents a person's link with a company.
  belongs_to :person
  belongs_to :company
end

class Shift
  # represents a daily shift that a company has
  belongs_to :company
end

class PersonShift
  # the system maps a person to the shift to indicate they showed up
  belongs_to :person
  belongs_to :shift
  enum status: { ongoing: "ongoing" } # and more
end

由于系统选择关联

Person
而不是
Employee
,现在编写查询来回答问题 “当前有多少员工处于活动状态?” 而不诉诸普通 SQL 有点困难。虽然这无论如何都不是问题,但我想知道是否有某种方法可以正确使用 ActiveRecord 来获得此结果。

现在,我能做的最好的就是:

date = Date.today

PersonShift.ongoing.joins(:shift).joins('INNER JOIN employees on employees.company_id = shifts.company_id AND employees.person_id = person_shifts.person_id').where(shifts: { date: }).distinct.select('employees.id')

根本问题是,将

Employee
连接到
PersonShift
需要查看
Shift
PersonShift
,并且不是一个简单的连接。希望有某种方法可以通过像
PersonShift
这样的东西直接关联
Employee
has_many through

我将无法修改这些表,因为这是一个遗留系统,需要花费大量的精力来迁移,而团队并不希望投入这些精力。

ruby-on-rails ruby activerecord ruby-on-rails-6.1
1个回答
0
投票

目前有多少员工处于轮班状态?

Person
Employee
之间的关联是一对一还是一对多?

如果是一对一的话,那么计算员工数和人数其实是一回事:

Employee.includes(:person_shifts).where(person_shift: {status: :ongoing, date: Date.today}).count

或者,如果是一对多,您仍然可以走捷径,选择具有不同

person_id
的员工:

Employee.includes(:person_shifts).where(person_shift: {status: :ongoing, date: Date.today}).select('distinct person_id')count

并添加到上面:一个

person
可能是两个不同的
employees
在同一天吗?您还没有真正解释这两个不同的表是什么/代表什么,所以我只是猜测。

© www.soinside.com 2019 - 2024. All rights reserved.