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

Always reload routes in UrlHelpers #2210

Closed
wants to merge 1 commit into from

Conversation

cquinones100
Copy link
Contributor

@cquinones100 cquinones100 commented Feb 20, 2025

Motivation

We are upgrading to Rails 8 and the generated RBIs for GeneratedUrlHelpersModule and GeneratedPathHelpersModule did not include any of our configured routes. The previous version of the UrlHelpers compiler links to rails/rails#52012, so I think the change was made to anticipate lazy loaded routes, but it does not seem to work in practice.

Implementation

Rails.application.reload_routes! produced the result I was looking for and I found that this also worked in Rails 7.

Tests

The old code did not break tests when CURRENT_RAILS_VERSION was set to 7.1 or 8.0.0, so some guidance on how to write a test for this would be appreciated. I am surprised that these tests weren't breaking.

@cquinones100 cquinones100 requested a review from a team as a code owner February 20, 2025 22:28
@paracycle
Copy link
Member

paracycle commented Feb 21, 2025

I am not sure that I understand how this is a problem. Even the follow up change in Rails 8 should still be loading all the routes when execute_unless_loaded is called. This is exactly the call that loads all the routes if the application is being loaded in eager_load mode, e.g. in production, so that should work in Tapioca, as well.

Can you give a minimal example of a Rails 8 app that doesn't work properly?

@cquinones100
Copy link
Contributor Author

Thanks for taking a look, @paracycle! I was not able to reproduce this issue with a fresh rails 8.0.1 application, so it probably is something to do with my app. I'll close this PR for now and do some digging. I'll reopen if I find something actionable.

@cquinones100
Copy link
Contributor Author

For posterity, and maybe a bit more feedback from you @paracycle, I found that devise caused this issue in my app. This line is executed at some point on boot and results in a shorter list of routes. Nothing more is loaded when tapioca attempts to execute_unless_loaded, because it has already loaded, of course.

I can configure devise to not load the routes, but I am hesitant to change my application code to get tapioca to work. We are not noticing this cause any issues in the actual application.

Unfortunately I am still unable to reproduce this exact issue with a minimal rails 8 application.

I don't think this information changes the solution I have in mind for my own application. I'm going to extend the UrlHelpers compiler and reload the routes directly, as demonstrated in the PR.

As for the future of this PR, does this unexpected behavior support the idea that this tapioca compiler should always be reloading the routes? Seeing as the loaded routes could be modified at some point upstream by unknown factors, shouldn't the compiler ensure that it is working with the expected data? Is the performance benefit granted by skipping the reload worth the risk?

@paracycle
Copy link
Member

Thanks for digging into this. The explanation makes sense but doesn't quite explain to me how your application is able to fully load its routes when eager loading, for example in production mode.

As I linked before, the call that gets made is again the execute_unless_loaded method, and the behaviour should be the same.

I suspect Tapioca's behaviour to be indicative of your app's production behaviour in this case. If my suspicion is correct, this might be preventing you from a production error.

Could you try to run your application either in production mode, or in eager load mode to see if your routes work fine?

@cquinones100
Copy link
Contributor Author

Hey @paracycle I should have mentioned in my comment that I ran my application in eager load mode and saw no issues. I added a breakpoint to the devise code and stepped through to confirm that it did not truncate the list of routes on boot. This seems to only occur when the app is booted by tapioca.

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