multiple_table_inheritance icon indicating copy to clipboard operation
multiple_table_inheritance copied to clipboard

Common Rails relationship idioms broken

Open mhuggins opened this issue 12 years ago • 0 comments

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.

mhuggins avatar Apr 09 '12 13:04 mhuggins