Skip to content

Type through associations whose source is polymorphic but pinned by source_type - #2755

Open
PhilMeyr wants to merge 1 commit into
Shopify:mainfrom
PhilMeyr:type-source-type-through-associations
Open

PhilMeyr wants to merge 1 commit into
Shopify:mainfrom
PhilMeyr:type-source-type-through-associations

Conversation

@PhilMeyr

Copy link
Copy Markdown

Motivation

A has_many/has_one :through association whose source is a polymorphic belongs_to is generated as untyped, even when source_type: pins the class:

class Client < ApplicationRecord
  has_many :safe_keeper_abilities
  has_many :safe_keepers, through: :safe_keeper_abilities, source: :resource, source_type: "SafeKeeper"
end
sig { returns(ActiveRecord::Associations::CollectionProxy) }
def safe_keepers; end

Rails resolves the class from source_type (Client.reflect_on_association(:safe_keepers).klass # => SafeKeeper), so the association can only hold SafeKeeper records. polymorphic_association? follows the source reflection, which is polymorphic, and ignores source_type.

#1990 fixed the same symptom by dropping the polymorphic check entirely, and was closed with a CI failure. This change is narrower: only a through reflection with source_type is treated as non-polymorphic. A polymorphic belongs_to and a through association without source_type are unchanged.

Implementation

polymorphic_association? returns false for a through reflection whose options include source_type. type_for and relation_type_for then use reflection.klass, which Rails computes from source_type.

Tests

Added a spec, with and without relations enabled, in spec/tapioca/dsl/compilers/active_record_associations_spec.rb:

  • has_many :through with source_type → ::SafeKeeper::PrivateCollectionProxy (::ActiveRecord::Associations::CollectionProxy[::SafeKeeper] without relations);
  • has_one :through with source_type → T.nilable(::SafeKeeper), and typed build_/create_/reload_ methods.

Both fail without the change.

@PhilMeyr
PhilMeyr requested a review from a team as a code owner October 29, 2026 08:58
@PhilMeyr PhilMeyr closed this Oct 29, 2026
@PhilMeyr PhilMeyr reopened this Oct 29, 2026
@PhilMeyr

Copy link
Copy Markdown
Author

I have signed the CLA!

@amomchilov

Copy link
Copy Markdown
Contributor

Thanks!

@amomchilov
amomchilov enabled auto-merge October 29, 2026 14:55
@amomchilov amomchilov added the enhancement New feature or request label Nov 5, 2026
@amomchilov
amomchilov force-pushed the type-source-type-through-associations branch from 6f3c8ca to 19bf601 Compare November 5, 2026 20:07

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants