Question

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?

Update:

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?

Update2:

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]}")
Was it helpful?

Solution

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:

  1. you still need typing the file names by yourself.

    def add_asset(*files)
    
  2. Several unnecessary helpers added when the jobs can be done elsewhere easily.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top