наследование одной таблицы, отношения has_many и сортировка - PullRequest
0 голосов
/ 10 декабря 2011

У меня настроены отношения 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 содержит список всех отчетов, поданных руководителем, и всех сотрудников, подотчетных менеджеру.

Я реализовал это следующим образом

  1. добавить метод класса employee_categories, в котором перечислены все типы сотрудников , в которые отправляются отчеты. например ['Manager', 'Member']
  2. Используйте приведенный выше список, чтобы сгенерировать список всех сотрудников , подающих отчеты e.g. Employee.where(:vicepresident_id => 3).where(:type => ['Manager', 'Member'])
  3. Готовые отчеты о загрузке для списка сотрудников из # 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, используя объединение таблиц вместо того, чтобы идти на эти длины?

1 Ответ

0 голосов
/ 10 декабря 2011

Для вопроса сортировки вы можете использовать default_scope с параметром :order , чтобы позволить базе данных выполнить вашу сортировку.

...