Shopify / tapioca

The swiss army knife of RBI generation
MIT License
722 stars 120 forks source link

Incompatible with gems that call `attribute` in Rails models #2004

Open ghiculescu opened 3 weeks ago

ghiculescu commented 3 weeks ago

I'm not sure if this is an issue with tapioca or with the downstream gem, but figured I'd report here and you can tell me to go away if necessary :)

To replicate:

It will raise like this:

/.rvm/gems/ruby-3.2.2/gems/activerecord-7.2.1/lib/active_record/connection_adapters/abstract/connection_handler.rb:224:in `retrieve_connection_pool': No connection pool for 'ActiveRecord::Base' found. (ActiveRecord::ConnectionNotEstablished)
    from /.rvm/gems/ruby-3.2.2/gems/activerecord-7.2.1/lib/active_record/connection_handling.rb:329:in `connection_pool'
    from /.rvm/gems/ruby-3.2.2/gems/activerecord-7.2.1/lib/active_record/connection_handling.rb:321:in `connection_db_config'
    from /.rvm/gems/ruby-3.2.2/gems/activerecord-7.2.1/lib/active_record/type.rb:50:in `adapter_name_from'
    from /.rvm/gems/ruby-3.2.2/gems/activerecord-7.2.1/lib/active_record/attributes.rb:299:in `resolve_type_name'
    from /.rvm/gems/ruby-3.2.2/gems/activemodel-7.2.1/lib/active_model/attribute_registration.rb:14:in `attribute'
    from /.rvm/gems/ruby-3.2.2/gems/noticed-2.4.1/app/models/noticed/event.rb:15:in `<class:Event>'
    from /.rvm/gems/ruby-3.2.2/gems/noticed-2.4.1/app/models/noticed/event.rb:2:in `<module:Noticed>'
    from /.rvm/gems/ruby-3.2.2/gems/noticed-2.4.1/app/models/noticed/event.rb:1:in `<main>'

The issue is the , :json here. If you remove that, it works fine, since it doesn't need to do the type lookup anymore.

As far as I'm aware, that approach of putting models in app/models for a gem is valid, but maybe there's a more correct way to structure the gem. In any case, it works fine everywhere apart from this specific case.

The underlying issue, I think, is that Rails thinks there's no connection pool set up. This is not an issue when you boot a Rails app, it's only an issue when tapioca is eager loading.

cc @excid3

KaanOzkan commented 1 day ago

Looks like it's being thrown from https://github.com/Shopify/tapioca/blob/316688e5725e95887caa3c61f0db870229c1a0a3/lib/tapioca/runtime/reflection.rb#L49-L53 It might be fine to add ActiveRecord::ConnectionNotEstablished to the rescue list and skip this constant. I'm not sure if there's anything else we can do.

If rescue can hide legitimate cases of "missing db connection" during tapioca dsl then we'd need a smarter implementation.