Reputation: 87
I'm running with some issues trying to combine STI and polymorphic associations with the following structure :
class User < ActiveRecord::Base
end
class Runner < User
has_many :subscriptions, as: :subscriber, :dependent => :destroy
has_many :areas, through: :subscriptions
end
class Trainer < Runner
end
class Subscription < ActiveRecord::Base
belongs_to :subscriber, polymorphic: true
belongs_to :area
end
class Area
end
When I try in the console :
Runner.find(2101).areas
SELECT "areas".* FROM "areas" INNER JOIN "subscriptions" ON "areas"."id" =
"subscriptions"."area_id" WHERE "subscriptions"."subscriber_id" = $1 AND
"subscriptions"."subscriber_type" = $2 [["subscriber_id", 2101], ["subscriber_type",
"User"]]
=> #<ActiveRecord::Associations::CollectionProxy []>
However there is a record with this runner :
#<Subscription id: 3, area_id: 2, subscriber_id: 2101, subscriber_type: "Runner", primary_area: true>
But I don't understand why active record is looking for a User and not a Runner.
Any idea why ? or better design ?
Upvotes: 5
Views: 4054
Reputation: 29349
From rails documentation
Using polymorphic associations in combination with single table inheritance (STI) is a little tricky. In order for the associations to work as expected, ensure that you store the base model for the STI models in the type column of the polymorphic association. To continue with the asset example above, suppose there are guest posts and member posts that use the posts table for STI. In this case, there must be a type column in the posts table.
Change your subscription class like this
class Subscription < ActiveRecord::Base
belongs_to :subscriber, polymorphic: true
belongs_to :area
def subscriber_type=(sType)
super(sType.to_s.classify.constantize.base_class.to_s)
end
end
Upvotes: 9