-
Notifications
You must be signed in to change notification settings - Fork 115
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
Improve template path detection for forms #3236
Merged
Merged
Conversation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
🦋 Changeset detectedLatest commit: b878ba2 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
camertron
force-pushed
the
better_form_path_detection
branch
from
December 10, 2024 00:01
08df9fe
to
e7bf8bf
Compare
camertron
changed the title
Improve form path detection
Improve template path detection for forms
Dec 10, 2024
jonrohan
approved these changes
Dec 13, 2024
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Merged
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
What are you trying to accomplish?
This PR adjusts the logic for detecting template paths for Rails forms. Like ViewComponents, Rails forms allow templates that follow specific naming conventions to be located adjacent to the form's .rb file. These templates enable two pieces of functionality:
bar
would render a caption template at foo_form/bar_caption.html.erb.When I originally added support for separate template files, I tried to use the new-ish
Module.const_source_location
method, which returns the absolute path to the file a particular constant was defined in. Doing so allows us to construct the template path for each form .rb file. Unfortunately, due to a bug in Ruby itself, this method returnedfalse
if the file was autoloaded, eg. by Zeitwerk, the Rails autoload system. The bug has since been fixed in newer versions of Ruby, but at the time was a blocker. To work around the problem, I introduced thePrimer::Forms::Utils.const_source_location
method that exploits the Zeitwerk requirement that files are named after the constants they define. In other words,FooForm
is required to live in foo_form.rb somewhere on the Rails load path. The workaround therefore was able to loop over each path in the Rails load path looking for a file with the same name as the given constant. This approach seemed to work fine.Before the advent of Zeitwerk, Rails used to manage autoloads via the
ActiveSupport::Dependencies
module, which still exists to this day. When adding support for template files, I noticed thatActiveSupport::Dependencies.autoload_paths
seemed to contain all the right autoload paths, including the very important app/forms directory. Unfortunately, as I have now learned, it does not contain all the autoload paths that may have been added eg. in application.rb. Dotcom does in fact add autoload paths in application.rb, but these paths are added to a Zeitwerk-specific data structure, i.e. notActiveSupport::Dependencies.autoload_paths
. Instead, Primer forms should iterate overRails.autoloaders.main.dirs
. I modified the code to do so, falling back toActiveSupport::Dependencies.autoload_paths
if Zeitwerk is not enabled (after all, PVC is used by apps outside of the GitHub monolith).I can hear you asking, "Why do this at all? Can't we just use
Module.const_source_location
now that Ruby bug has been fixed and released?" Wow, I can see you were paying attention. You're absolutely right! That's where the second change in this PR comes from - usingModule.const_source_location
and falling back toPrimer::Forms::Utils.const_source_location
when necessary. Doing so should work for a sufficiently large matrix of Ruby and Rails versions.Finally, this PR also contains a bit of a refactoring to prevent calling
Module.const_source_location
before the constant has been defined and the old autoload replaced. CallingModule.const_source_location
too early (i.e. inincluded
callbacks) will return the path to an internal Zeitwerk file (cref.rb), which I assume is the file that defines the autoload. The autoload has not been cleaned up by the timeincluded
is called, so we have to do it later. This turns out to be a cleaner approach anyway, as it does not require us to settemplate_root_path
on form classes. Nice.Integration
No changes necessary in production, everything in this PR should be backwards-compatible.
List the issues that this change affects.
Fixes: https://github.com/github/primer/issues/4500
Risk Assessment
What approach did you choose and why?
See above.
Accessibility
Merge checklist
Take a look at the What we look for in reviews section of the contributing guidelines for more information on how we review PRs.