Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove polymorphic check when generating associating methods #1990

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

matthewarkin
Copy link

@matthewarkin matthewarkin commented Aug 14, 2024

Motivation

We noticed when adding some typing to our code that association methods for polymorphic associations were returning a generic ActiveRecord::Associations::CollectionProxy instead of the Model::PrivateCollectionProxy that is used elsewhere in tapioca.

Implementation

I believe checking for the polymorphicness of the association is actually unnecessary since it shouldn't ever be the case that the association for a has_many would return a collection of different types.

Tests

I updated the existing tests to reflect the updated behavior. I don't think I'm missing a test case but thats mostly because I can't think of a case where you woudn't be able to pin the method to a specific model/type.

When doing a has_many with a polymorphic association, these were previously a generic/untyped collectionproxy. I'm not actually sure that needs to be the case since it appears that you should be getting a CollectionProxy of the model of the association.
@matthewarkin matthewarkin requested a review from a team as a code owner August 14, 2024 18:58
@matthewarkin
Copy link
Author

I have signed the CLA!

Copy link
Contributor

@amomchilov amomchilov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @matthewarkin, thanks for your first contribution!

We'd be happy to merge this in, but there's an error in our CI that I don't have time to troubleshoot and fix myself. Could you take a look?

@@ -287,7 +287,7 @@ def populate_collection_assoc_getter_setter(klass, association_name, reflection)
def type_for(reflection)
validate_reflection!(reflection)

return "T.untyped" if !constant.table_exists? || polymorphic_association?(reflection)
return "T.untyped" if !constant.table_exists?

T.must(qualified_name_of(reflection.klass))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmmm, I'm getting a failure when running against our core monolith:

Error: `Tapioca::Dsl::Compilers::ActiveRecordAssociations` failed to generate RBI for `OurModel`
--
  | /tmp/bundle/ruby/3.4.0+0/bundler/gems/rails-f0fd6ab1259b/activerecord/lib/active_record/reflection.rb:500:in 'ActiveRecord::Reflection::AssociationReflection#compute_class': Polymorphic associations do not support computing the class. (ArgumentError)
  |  
  | raise ArgumentError, "Polymorphic associations do not support computing the class."
  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  | from /tmp/bundle/ruby/3.4.0+0/bundler/gems/rails-f0fd6ab1259b/activerecord/lib/active_record/reflection.rb:439:in 'ActiveRecord::Reflection::MacroReflection#_klass'
  | from /tmp/bundle/ruby/3.4.0+0/bundler/gems/rails-f0fd6ab1259b/activerecord/lib/active_record/reflection.rb:431:in 'ActiveRecord::Reflection::MacroReflection#klass'
  | from /tmp/bundle/ruby/3.4.0+0/bundler/gems/tapioca-b0eab561b24b/lib/tapioca/dsl/compilers/active_record_associations.rb:292:in 'Tapioca::Dsl::Compilers::ActiveRecordAssociations#type_for'

Where OurModel looks something like this, with a polymorphic belongs_to:

class OurModel < ApplicationRecord
   belongs_to :reference, polymorphic: true
end

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome, this is super useful, I can work on this

@@ -287,7 +287,7 @@ def populate_collection_assoc_getter_setter(klass, association_name, reflection)
def type_for(reflection)
validate_reflection!(reflection)

return "T.untyped" if !constant.table_exists? || polymorphic_association?(reflection)
return "T.untyped" if !constant.table_exists?
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lint fix:

Suggested change
return "T.untyped" if !constant.table_exists?
return "T.untyped" unless constant.table_exists?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants