在使用STI时从rails 3的has_many关联中获取集合时,我遇到了一些奇怪的行为.我有:
class Branch < ActiveRecord::Base has_many :employees,class_name: 'User::Employee' has_many :admins,class_name: 'User::BranchAdmin' end class User < ActiveRecord::Base end class User::Employee < User belongs_to :branch end class User::BranchAdmin < User::Employee end
期望的行为是branch.employees返回所有员工,包括分支管理员.当branch.admins访问分支管理员时,它们似乎只在这个集合下被“加载”,这是从控制台输出的:
Branch.first.employees.count => 2 Branch.first.admins.count => 1 Branch.first.employees.count => 3
SELECT COUNT(*) FROM "users" WHERE "users"."type" IN ('User::Employee') AND "users"."branch_id" = 1
第二次:
SELECT COUNT(*) FROM "users" WHERE "users"."type" IN ('User::Employee','User::BranchAdmin') AND "users"."branch_id" = 1
class Branch < ActiveRecord::Base has_many :employees,class_name: 'User' has_many :admins,class_name: 'User::BranchAdmin' end
因为它们都是从他们的branch_id中找到的,但这会在控制器中产生问题,如果我想做branch.employees.build那么该类将默认为User,我必须在某处修改type列.我现在已经解决了这个问题:
has_many :employees,class_name: 'User::Employee',finder_sql: Proc.new{ %Q(SELECT users.* FROM users WHERE users.type IN ('User::Employee','User::BranchAdmin') AND users.branch_id = #{id}) },counter_sql: Proc.new{ %Q(SELECT COUNT(*) FROM "users" WHERE "users"."type" IN ('User::Employee','User::BranchAdmin') AND "users"."branch_id" = #{id}) }
但如果可能,我真的想避免这种情况.任何人,任何想法?
编辑:
finder_sql和counter_sql还没有真正解决它,因为看起来父联想似乎没有使用它,所以organisation.employees has_many:employees,通过:: branches将再次只在选择中包含User :: Employee类.