I don't want use a //= require_tree .
(because it loads all the assets I have, which I also don't need) and don't want write each time javasctipt_include_tag("my_controller")
. So I decided to do following:
module ApplicationHelper
def add_asset(*files)
puts "DEBUG: add: " + files.to_s
content_for(:html_head) do
if GtFe::Application.assets.find_asset(*files)
yield :asset_include_tag
end
end
end
def javascript(*files)
add_asset(*files) do
content_for :asset_include_tag
javascript_include_tag(*files)
end
end
def stylesheet(*files)
add_asset(*files) do
content_for :asset_include_tag
stylesheet_link_tag(*files)
end
end
end
So I use name named yields in helper methods and I have a main add_asset()
method and two asset-specific methods. Is it a good way to do so? Or are any better solutions available?
From the rails docs:
For example, if you generate a ProjectsController, Rails will also add a new file at app/assets/javascripts/projects.js.coffee and another at app/assets/stylesheets/projects.css.scss. By default these files will be ready to use by your application immediately using the require_tree directive. See Manifest Files and Directives for more details on require_tree.
You can also opt to include controller specific stylesheets and JavaScript files only in their respective controllers using the following: <%= javascript_include_tag params[:controller] %> or <%= stylesheet_link_tag params[:controller] %>. Ensure that you are not using the require_tree directive though, as this will result in your assets being included more than once.
So the javascript_include_tag
and stylesheet_link_tag
are justified. But is it good so to do this yield staff to DRY?
I landed with this code refinements:
module ApplicationHelper
def add_asset(asset_type, *files)
puts "DEBUG: add #{asset_type} files: #{files}"
content_for(:html_head) do
files.each do |file|
puts "DEBUG: now add #{asset_type}: #{file}"
if GtFe::Application.assets.find_asset(file)
yield(:asset_include_tag, file)
end
end
end
end
def javascript(*files)
add_asset("js", *files) do
content_for :asset_include_tag
javascript_include_tag
end
end
def stylesheet(*files)
add_asset("css", *files) do
content_for :asset_include_tag
stylesheet_link_tag
end
end
end
And then I can write in each view/layout so:
= javascript(params[:controller], "#{params[:controller]}_#{params[:action]}")
I think this is overkill.
If you don't like require full tree unordered, you can require them manually one by one.
//= js_file_a
//= js_file_b
Comparing with your solution:
you still need typing the file names by yourself.
def add_asset(*files)
Several unnecessary helpers added when the jobs can be done elsewhere easily.