web-dev-qa-db-ja.com

Rails 3.1アセットパイプライン:コントローラー固有のスクリプトを読み込む方法は?

Rails 3.1で新しいコントローラーを生成すると、コントローラーの名前を持つjavascriptファイルも自動的に追加されます。まず、このjavascriptファイルは関連するコントローラーが呼び出されたときにのみ使用されると思いました。

デフォルトでは、命令//= require_tree . の中に application.js-ファイル。ツリー上のすべてのjavascriptファイルが含まれます。

コントローラー固有のスクリプトのみを読み込むにはどうすればよいですか?

76
Mike Bevz

必要なname_of_the_js_file.jsファイルのみをロードするには:

  1. //=require_treeからapplication.jsを削除します

  2. jsファイル(特定のページの読み込み時に読み込む)をアセットパイプラインに保持します

  3. application_helper.rbにヘルパーを追加します

    def javascript(*files)
      content_for(:head) { javascript_include_tag(*files) }
    end
    
  4. あなたのレイアウトに譲ります:

    <%= yield(:head) %>
    
  5. これをビューファイルに追加します。

    <% javascript 'name_of_the_js_file' %>
    

それで大丈夫です

122

このためのエレガントなソリューションは、javascript_include_tagにcontroller_nameを要求することです

http://apidock.com/Rails/ActionController/Metal/controller_name/class を参照してください

<%= javascript_include_tag "application", controller_name %>

controller_name.jsが読み込まれ、アセットにも含まれているため、ここから他のファイルを要求できます。

例、cars#indexをレンダリングすると

<%= javascript_include_tag "application", "cars" %>

cars.jsに含めることができる場所

//= require wheel
//= require tyre

楽しい !

83
albandiguer

レイアウトファイルには常にこれを含めます。 jsをアクションにスコープできます

<%= javascript_include_tag params[:controller] if AppName::Application.assets.find_asset("#{params[:controller]}.js") %>
<%= javascript_include_tag "#{params[:controller]}_#{params[:action]}"  if AppName::Application.assets.find_asset("#{params[:controller]}_#{params[:action]}.js") %>
28
Le Duc Duy

問題はさまざまな方法で解決できます。

アセットを動的に追加します

コントローラの仕様はプリコンパイルされないため、これは本番モードには適したソリューションではないことを考慮してください!

  1. 次のメソッドをアプリケーションヘルパーに追加します。

    module ApplicationHelper
        def include_related_asset(asset)
        #          v-----{Change this}
            if !YourApp::Application.assets.find_asset(asset).nil?
                case asset.split('.')[-1]
                    when 'js'
                        javascript_include_tag asset
                    when 'css'
                        stylesheet_link_tag asset
                end
            end
        end
    end
    
  2. layout-ファイルでヘルパーメソッドを呼び出します。

    <%= include_related_asset(params[:controller].to_param + '_' + params[:action].to_param . 'js') %>
    
  3. コントローラーアクション用の特定のアセットを作成します。例controller_action.js

YourAppをアプリの名前に変更することを忘れないでください。

yieldを使用

  1. <%= yield :head%>をレイアウトヘッドに追加します
  2. アクションビューからアセットを含めます。

    <% content_for :head do %>
    <%= javascript_include_tag 'controller_action' %>
    <% end %>
    

詳細については Railsガイド をご覧ください。

6
Robin

albandiguerの解 が好きです。これにより、javascript/coffeescriptアセットが個別にプリコンパイルされていないことがわかりました。 javascript_pathを使用しようとすると、あらゆる種類のエラーが発生します。いくつかの人が彼のコメントで言及した問題に対処した後、その問題に対する私の解決策を共有します。主にJavaScriptファイルという名前のコントローラーの部分セットのみを処理します。

そこで、.coffee/.js拡張子に関係なくファイルがjavascriptディレクトリに存在するかどうかを検出するアプリケーションヘルパーを作成しました。

module ApplicationHelper
  def javascript_asset_path(basename)
    Sprockets::Rails::Helper.assets.paths.select{|i|
      i =~ /javascript/ and i =~ /#{Rails.root}/
    }.each do |directory|
      if Dir.entries(directory).map {|i| i.split('.')[0]}.compact.
          include? basename
        return File.join(directory, basename)
      end
    end
    nil
  end
end

このメソッドは、javascriptファイルが存在する場合、そのフルパスを返します。それ以外の場合は、nilを返します。したがって、Pencilcheckのコメントに従って、条件付きインクルードにこのメソッドを追加できます。

<%= javascript_include_tag(controller_name) if javascript_asset_path(controller_name) %>

そして今、あなたは適切な条件付きインクルードを持っています。次に、プリコンパイル済み資産の問題に​​ついて説明します。通常、最適化のためにアセットをプリコンパイルしたくない個別に。ただし、必要な場合は実行できます。

# Live Compilation
config.assets.compile = true

これを環境設定ファイルに追加できます。最初に開発環境ファイルでテストします。繰り返しますが、これはお勧めできません。 Railsアセットパイプラインはスプロケットを使用してすべてを最適化します。

スプロケットは、指定されたファイルをロードし、必要に応じて処理し、それらを1つのファイルに連結して圧縮します(Rails.application.config.assets.compressがtrueの場合)。多数のファイルではなく1つのファイルを提供することにより、ブラウザーが行う要求が少なくなるため、ページのロード時間を大幅に短縮できます。また、圧縮によりファイルサイズが小さくなり、ブラウザでのダウンロードが高速化されます。

お読みくださいSprockets(Asset Pipeline)http://guides.rubyonrails.org/asset_pipeline。 html

アセットは個別にプリコンパイルされません。たとえば、私がしようとすると:

<%= javascript_include_tag 'event' %>

私は得る:

Sprockets :: Rails :: Helper :: AssetFilteredError:アセットは除外されて配信されません:Rails.application.config.assets.precompile += %w( event.js )config/initializers/assets.rbに追加してサーバーを再起動します

したがって、個別にプリコンパイルするアセットを含めることができます。アセット初期化子にjavascriptファイルという名前の関連コントローラーを追加するだけです。これをプログラムで行うことができます。

コントローラー名のリストを取得するには、 ecoologicの例 を使用します。

all_controllers =  Dir[
    Rails.root.join('app/controllers/*_controller.rb')
  ].map { |path|
    path.match(/(\w+)_controller.rb/); $1
  }.compact

そして、コントローラ名のベース名に一致するすべてのjavascriptファイルの名前を取得するには、次を使用できます。

javascripts_of_controllers = Sprockets::Rails::Helper.assets.paths.select{|a_path|
    a_path =~ /javascript/ and a_path =~ /#{Rails.root}/
  }.map {|a_path|
    Dir.entries(a_path)
  }.flatten.delete_if {|the_file|
    !the_file['.js']
  }.collect {|the_file|
    the_file if all_controllers.any? {|a_controller| the_file[a_controller]}
  }

その後、試すことができます:

# config/initializers/assets.rb
Rails.application.config.assets.precompile += javascripts_of_controllers

これにより、コントローラー名に一致するすべてのjavascriptファイルのリストがディレクトリパスなしで取得されます。コントローラ名が複数の場合、javascript名も同じである必要があります。また、コントローラーが単数形であり、javascriptファイルが複数形である場合、the_file[a_controller]が部分一致で成功するため、これも引き続き含まれます。

Rails.application.config.assets.precompile設定でこれを試してみてください。これにより、ファイルのリストが正しく取得されます。しかし、私はあなたにそれをテストさせます。興味があるので、この方法でプリコンパイルすることに微妙な違いがあるかどうか教えてください。

アセットのプリコンパイル方法に関する非常に詳細な説明については、このブログを参照してください。 http://www.sitepoint.com/asset-precompile-works-part/

3
6ft Dan

私は最近、特定のコントローラー用に生成されたスクリプトを使用する簡単なアプローチを見つけました。私はそのソリューションに使用します gem gon 。コントローラーを追加します。

class HomesController < ApplicationController
  before_filter :remember_controller

  private

  def remember_controller
    gon.controller = params[:controller]
  end
end

その後、homes.js.cofeeおよびファイルの先頭に追加します。

jQuery ->
  if gon.controller == "sermons"
    # Place all functions here...

それだけです。

1
ExiRe