我正在开发 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
?
我将无法修改这些表,因为这是一个遗留系统,需要花费大量的精力来迁移,而团队并不希望投入这些精力。
目前有多少员工处于轮班状态?
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
在同一天吗?您还没有真正解释这两个不同的表是什么/代表什么,所以我只是猜测。