multiple_table_inheritance
multiple_table_inheritance copied to clipboard
Common Rails relationship idioms broken
The current implementation of multiple_table_inheritance breaks various Rails idioms. For example, take the following example:
class Employee < ActiveRecord::Base
acts_as_superclass
attr_reader :first_name, :last_name
has_many :employees_permissions
has_many :permissions, :through => :employees_permissions
end
class Programmer < ActiveRecord::Base
inherits_from :employee
end
class Permission < ActiveRecord::Base
attr_reader :name, :description
has_many :employees_permissions
has_many :employees, :through => :employees_permissions
end
class EmployeesPermission < ActiveRecord::Base
belongs_to :employee
belongs_to :permission
end
Basically, each employee has many permissions, and conversely, each permission can be associated with multiple employees.
Let's say now that we want to retrieve all the employees associated with a permission:
permission = Permissions.find(1)
permissions.employees
This returns an array of <Programmer> objects instead of <Employee> objects, as is expected by using this gem.
However, let's pretend we want to know how many permissions are associated with any given employee. This is generally done via a counter_cache
. Here's a simple change that will allow this:
class EmployeesPermission < ActiveRecord::Base
belongs_to :employee, :counter_cache => true
end
class Employee < ActiveRecord::Base
attr_reader :permission_count
end
Unfortunately, this results in the SQL UPDATE being performed against the Programmer model's table instead of the Employee model's table. Since permission_count
exists on the employees
table and not the programmers
table, this results in a SQL error.