I get weird behavior when dialing collections from has_many association with rails 3 when using STI. I have:
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
The desired behavior is that branch.employees
returns all employees, including branch administrators. Branch administrators only seem to be βloadedβ in this collection, when branch.admins
accesses branch.admins
, this is output from the console:
Branch.first.employees.count => 2 Branch.first.admins.count => 1 Branch.first.employees.count => 3
This can be seen in the generated SQL for the first time:
SELECT COUNT(*) FROM "users" WHERE "users"."type" IN ('User::Employee') AND "users"."branch_id" = 1
and second time:
SELECT COUNT(*) FROM "users" WHERE "users"."type" IN ('User::Employee', 'User::BranchAdmin') AND "users"."branch_id" = 1
I could solve this problem by simply specifying:
class Branch < ActiveRecord::Base has_many :employees, class_name: 'User' has_many :admins, class_name: 'User::BranchAdmin' end
since they are all found from their branch_id, but this creates problems in the controller, if I want to do branch.employees.build
, then the default class will be User
, and I have to hack something in the type column. I went around this now:
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 =
but I would really like to avoid this, if possible. Anyone any ideas?
EDIT:
Finder_sql and counter_sql did not actually solve this for me, because it seems that the parent associations are not using it, and therefore the organisation.employees
that has_many :employees, through: :branches
will only include the User::Employee
class in the selection again.