Polymorphic Association with Single Table Inheritance?

Hello,

is it possible to setup a model/table schema like this:

Groupable --> Membership <-- Group
^ ^
| |
User UserGroup

I tried the following but failed:

Groupable (table with ‘type’ column)
has_many :memberships, :as => :groupable
has_many :groups, :through => :memberships

Membership
belongs_to :groupable, :polymorphic => true
belongs_to :group, :polymorphic => true

Group (table with ‘type’ column)
has_many :memberships, :as => :group
has_many :groupables, :through => :memberships

And the inherited tables:

User < Groupable
has_many :user_groups, :through => :memberships

UserGroup < Group
has_many :users, :through => :memberships

Setting up an user, a membership and an user_group
works, but it throws an exception on accessing
user_group.users:

ruby script/console
u = User.create
m = Membership.create
ug = UserGroup.create
u.memberships << m
ug.memberships << m
ug.users
ActiveRecord::HasManyThroughAssociationPolymorphicError:
ActiveRecord::HasManyThroughAssociationPolymorphicError

Thanks for any help!

Greets,
Stephan

Stephan S. wrote:

Hello,

is it possible to setup a model/table schema like this:

Groupable → Membership ← Group
^ ^
| |
User UserGroup

I tried the following but failed:

Groupable (table with ‘type’ column)
has_many :memberships, :as => :groupable
has_many :groups, :through => :memberships

Membership
belongs_to :groupable, :polymorphic => true
belongs_to :group, :polymorphic => true

Group (table with ‘type’ column)
has_many :memberships, :as => :group
has_many :groupables, :through => :memberships

And the inherited tables:

User < Groupable
has_many :user_groups, :through => :memberships

UserGroup < Group
has_many :users, :through => :memberships

Setting up an user, a membership and an user_group
works, but it throws an exception on accessing
user_group.users:

ruby script/console
u = User.create
m = Membership.create
ug = UserGroup.create
u.memberships << m
ug.memberships << m
ug.users
ActiveRecord::HasManyThroughAssociationPolymorphicError:
ActiveRecord::HasManyThroughAssociationPolymorphicError

has_many :through works just fine with STI, however it has some issues
with polymorphism. I have an explanation and a partial workaround here:
http://blog.hasmanythrough.com/articles/2006/04/03/polymorphic-through

But it doesn’t look like you are doing STI at all, just garden-variety
polymorphism. The terminology can be confusing, as generic OOP
inheritance allows polymorphism through specialization, meaning a
subclass can be used in place of a superclass. But in Rails STI just
means the models get their data from the same table, which allows the
type information to be encapsulated in the model itself (in the ‘type’
field in the table), rather than being placed alongside the groupable_id
foreign key in the groupable_type field. You only need to have the type
in one place, so only use STI or :as => :typeable.


Josh S.
http://blog.hasmanythrough.com

Josh S. wrote:

But it doesn’t look like you are doing STI at all, just garden-variety
polymorphism.

Ah, got the point now. A table containing all attributes of all possible
‘subclasses’…

Thank you, read all your blog entries about rails - pretty good stuff :slight_smile:

Greets,
Stephan