I am updating a Rails template to v.7 and I'm running into a challenge with updating the dynamic calls to load various Javascript and stylesheets based on the controller/action.
<%= javascript_include_tag controller_name if ::Rails.application.assets.find_asset(controller_name) %>
works fine as expected. This code loads a Javascript file into the asset pipeline if the file exists, based only on the current controller.
However, when I try to access the same controller with a dependent action, I'm getting a
The asset "static/landing.js" is not present in the asset pipeline.
error with the following code:
<%= javascript_include_tag("#{controller_name}/#{action_name}") if ::Rails.application.assets.find_asset("#{controller_name}/#{action_name}") %>
The file in question doesn't exist, but the code listed is supposed to catch it if it isn't and not render the javascript_include_tag
call if the file doesn't exist in the app/assets/javascripts
tree.
Any ideas?
Ok, so the answer proved to be simple but a little elusive; here we go...
Since Rails 4 you have been able to drop the .js
filetype designation from the end of the reference and Rails picked it up through the asset pipeline. After some serious soul-searching and offerings of caffeine to the coding-gods, I threw it back in on an attempt to reset my refactoring... and it worked.
Here is the final code that goes into my application.html.erb
file:
<%= javascript_include_tag 'application', 'data-turbo-track': 'reload' %>
<%= javascript_include_tag ("#{controller_name}"), 'data-turbo-track': 'reload' if ::Rails.application.assets.find_asset("#{controller_name}.js") %>
<%= javascript_include_tag ("#{controller_name}/#{action_name}"), 'data-turbo-track': 'reload' if ::Rails.application.assets.find_asset("#{controller_name}/#{action_name}.js") %>
The same syntax works for stylesheets as well, so feel free to copy it down if you need dynamic stylesheets.
What this code block does is allow you to minimize the content of the application.js(.erb)
file to the bare-bones. I found in the past, mine tended to get rather bloated, hence my search for something more dynamic and adaptable. I can now add a Javascript/stylesheet file for each controller and child action if I need to address something specific without worrying about sprockets bloat for unnecessary or unused code, yet it degrades nicely if I haven't needed to create the file(s).
NOTE: I haven't benchmarked this yet, but I hope that it will provide a nice performance boost.