Shopify / tapioca

The swiss army knife of RBI generation
MIT License
701 stars 115 forks source link

update activerecord.rbi to account for new preferred method for model validations #1932

Closed mikeheft closed 1 month ago

mikeheft commented 1 month ago

In the active_record RBI file, it has the validations but they are the older style, e.g.v def validates_presence_of(*attr_names); end. I found a workaround for the issue with has_many, here.

Would be nice to have support for the newer syntax, is there any workaround like for the has_many issue?

KaanOzkan commented 1 month ago

I'm not sure what error you're running into. Is there an issue with using validates :foo in your Rails model?

mikeheft commented 1 month ago

Yes. It comes up and method doesn't exist on T.classof(Model). And looking at the rbi for active record it's using the older 'validates<presence|uniquness|etc>_of'. I had updated it manually to have 'def validaties(*attributes, **opts); end' but I'm not sure how safe/accurate that is.

KaanOzkan commented 1 month ago

It should be defined in activemodel RBI, e.g.: https://github.com/Shopify/tapioca/blob/35a6a43b5469d5b03d292330449fd7b6db7593a6/sorbet/rbi/gems/activemodel%407.1.3.4.rbi#L5647C3-L5647C16

It should be loaded if you have gem "rails" in the Gemfile.

mikeheft commented 1 month ago

Huh, good to know. But it wasn't recognizing it. I had run the tapioca init/annotations/dsl commands multiple times and it wasn't until I added it to the active_record rbi that it stopped raising the error. Is there a specific require that's needed in the tapioca require.rb? I know that models inherit from ApplicationRecord which in turn inherits from ActiveRecord::Base and in active_record/base.rb there's an include ActiveModel::API, link

KaanOzkan commented 1 month ago

You need to make sure you depend on activemodel and run bin/tapioca gem or bin/tapioca gem activemodel to regenerate the RBI file. You can get around this issue by defining it manually like you did (usually under sorbet/rbi/shims/ folder) but that shouldn't be needed in a normal setup.

mikeheft commented 1 month ago

Ahh ok. So if It's not recognizing some rails dep or any other gem, I do the above. Sounds good thank you! Sorry for my confusion on this part. I have exp with sorbet just not on the initial set up :( thanks again!

KaanOzkan commented 1 month ago

Yes gem and dsl are different. Also after the initial setup you don't have to run init. I suggest taking a look at the readme which will explain it further. require.rb is also a possible solution to tell tapioca to load a specific file before gem generation but it shouldn't be needed. Feel free to send a reproduction repo if it persists.