使用STI時,當從rails3的has_many關聯中獲取集合時,出現了一些奇怪的行爲。我有:Rails STI與小類的關聯
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
這可以在生成的SQL中可以看出,第一時間:
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
,我必須在類型列某處破解這會在控制器的問題。我已經解決了這個問題:
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, through: :branches
再次只包括在選擇的User::Employee
類。
這是一個很棒的結果,謝謝。模型結構實際上已經改變了,所以問題消失了,但我不認爲我甚至會認爲它是環境的影響! –