У меня настроены отношения STI и has_many между сотрудниками и поданными ими отчетами. Команда сотрудников структурирована в базе данных с использованием наследования одной таблицы, как показано ниже.
class Employee < ActiveRecord::Base
has_many :reports
#More code goes here. Scroll down for details
end
class Vicepresident < Employee
has_many :managers
has_many :members
end
class Manager < Employee
has_many :members
belongs_to :vicepresident
end
class Member < Employee
belongs_to :manager
belongs_to :vicepresident
end
Я хочу иметь метод, который перечисляет все отчеты, поданные сотрудником, и все сотрудники, сообщающие в цепочку. Так, например, (i) vp = Vicepresident.first; vp.all_reports
перечислены все отчеты, поданные вице-президентом, менеджерами, отчитывающимися перед ним/ней, и всеми членами команды, отчитывающимися перед менеджерами. (ii) mgr = Manager.first; mgr.all_reports
перечислены все отчеты, поданные менеджером, и все сотрудники, подчиняющиеся менеджеру.
Как я это реализовал, так это
- добавьте метод класса employee_categories, в котором перечислены все типы сотрудников. например
['Manager', 'Member']
- Используйте приведенный выше список, чтобы создать список всех сотрудников, которым подчиняются.
e.g. Employee.where(:vicepresident_id => 3).where(:type => ['Manager', 'Member'])
- Нетерпеливые отчеты о загрузке для списка сотрудников из # 2.
e.g. Employee.where(:vicepresident_id => 3).where(:type => ['Manager', 'Member']).include(:reports)
Код для № 1, № 2 и № 3 показан здесь --
class Employee < ActiveRecord::Base
has_many :reports
def self.employee_categories
self.reflect_on_all_associations(:has_many)
.reject{|a| a.active_record.superclass.name != "Employee"}
.collect {|a| a.name.to_s.singularize.capitalize}
end
def team_members
id = self.class.name.downcase + "_id"
Employee.where(id => self.id).where(:type => self.class.employee_categories)
end
def all_reports
reports = []
self.team_members.include(:reports).each do |emp|
reports << emp.reports
end
return reports.flatten.sort {|x,y| y.created_at <=> x.created_at}
end
end
Я хочу делегировать функции сортировки в all_reports SQL вместо Ruby. Как я могу это сделать? Кроме того, есть ли более простой способ сделать all_reports с использованием соединений таблиц вместо того, чтобы идти на эти длины?