单表继承,has_many关系和排序

时间:2011-12-10 02:06:25

标签: ruby-on-rails has-many eager-loading single-table-inheritance self-join

我在员工和他们提交的报告之间设置了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)
  4. 此处显示的#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 :(得分:0)

对于排序问题,您可以use a default_scope with an :order parameter让数据库进行排序。