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

SystemStackError for has_many assocation that points to own model #1883

Open
jackwurth opened this issue Apr 25, 2024 · 4 comments
Open

SystemStackError for has_many assocation that points to own model #1883

jackwurth opened this issue Apr 25, 2024 · 4 comments

Comments

@jackwurth
Copy link

I have a setup involving a model with a has_many that points to itself

class Group < ApplicationRecord
    has_many :sub_groups, class_name: "Group", primary_key: "id", foreign_key: "parent_id"
end

each record has a parent_id to point to it's parent group.

This setup works fine with rails, but tapioca crashes when it tries to generate it with a SystemStackError

activerecord-7.1.3.2/lib/active_record/reflection.rb:967:in 'through_reflection': stack level too deep (SystemStackError)`
...
/thor-1.3.1/lib/thor/base.rb:584:in start
/tapioca-0.13.3/exe/tapioca:25:in '<top (required)>

Tested with Tapioca version 0.13.3

@KaanOzkan
Copy link
Contributor

I wasn't able to reproduce. If you can share a small app that has the same problem I can take a look.

@jackwurth
Copy link
Author

Ah my bad it turns out that there's more to it than what I thought, the traceback doesn't really point to the source of the error.

I've uploaded a demo here: https://github.com/jackwurth/sorbet_bug_demo
Also attached as zip: sorbet_test.zip

The test setup is:
Group A
Group B with parent set to "Group A"
Member A with group set to "Group B"

Running bundle exec tapioca dsl triggers the crash. Rails can handle this weird setup just fine.

it seems the cause is more likely to be to do with the has_many that calls a method.
https://github.com/jackwurth/sorbet_bug_demo/blob/main/app/models/group.rb#L11

@KaanOzkan
Copy link
Contributor

We are triggering the recursive calls here which eventually attempts to call Reflection.class_name.

There might be a better way to do this but I think we can filter out this case by checking if reflection.source_reflection_name matches reflection.delegate_reflection.name.

@KaanOzkan
Copy link
Contributor

@paracycle do you have context on the internals? We enter infinite recursion while validating a has_many through association that points to the same model https://github.com/jackwurth/sorbet_bug_demo/blob/main/app/models/group.rb#L8.

I was thinking if we can reliably detect this by looking at the reflection name (above comment) we could skip validating and return T.untyped?

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

No branches or pull requests

2 participants