Using Rails 7
I am using a Single Table Inheritance (STI) to store some very simple associations. The source object uses has_many associations with the STI models. Following some advice in question https://stackoverflow.com/a/45681641/1014251 I am using a polymorphic relationship in the join model. This works really well with one annoyance:
When creating a join models the source type is being taken from the root STI class rather than the actual source.
The models:
class Guidance < ApplicationRecord
has_many :guidance_details
has_many :themes, through: :guidance_details, source: :detailable, source_type: "Theme"
end
class Detail < ApplicationRecord
has_many :guidance_details, as: :detailable
has_many :guidances, through: :guidance_details
end
class GuidanceDetail < ApplicationRecord
belongs_to :detailable, polymorphic: true
belongs_to :guidance
end
class Theme < Detail
end
The problem
If I create a new GuidanceDetail and do not specify the detailable_source the system inserts "Detail" rather than "Theme".:
guidance_detail = GuidanceDetail.create(guidance: Guidance.first, detailable: Theme.first)
guidance_detail.detailable_type => "Detail"
The detailable type should be "Theme".
To fix this currently I am having to specify the detailable_type each time I create a new GuidanceDetail.
A fix that doesn't work
I have tried specifying the has_many association of the child object directly, but get the same result:
class Theme < Detail
has_many :guidance_details, as: :detailable
end
Alternative creation method doesn't work
theme = Theme.first
guidance = Guidance.first
guidance.themes << theme
Outputs:
GuidanceDetail Create (1.3ms) INSERT INTO "guidance_details" ("detailable_id", "guidance_id", "position", "created_at", "updated_at", "detailable_type") VALUES ($1, $2, $3, $4, $5, $6) RETURNING "id" [["detailable_id", 11], ["guidance_id", 1], ["position", nil], ["created_at", "2024-11-14 10:24:19.785623"], ["updated_at", "2024-11-14 10:24:19.785623"], ["detailable_type", "Detail"]]
As you see: "detailable_type" is "Detail".