概要
コントローラやアクセスしたページ毎に必要な静的ファイルを読み込みたい!という要望を叶える方法は多々ありますが、今回ご紹介するのは Asset Pipelineの恩恵を損なわずにページ毎に必要最低限なファイルを読み込むという手法でございます。
ざっくり説明
下記説明にはAsset PipelineのJavaScript側を例にとっていますが、CSS側も適宜読み替えて頂ければ同様の効果が得られます
- [1]
application.js
には「全ページ共通で読み込むファイル」を記載 - [2] 任意で読み込みたいファイルは
assets/javascripts/コントローラパス.js
を作成 - [3]
initializers/assets.rb
内のRails.application.config.assets.precompile
に[2]のパスを追記 - [4]
layouts/application.html.erb
から現在アクセスしているコントローラパスをヘルパーに渡す - [5]
app/helpers/application_helper.rb
が[4]の内容を受け取りファイル存在確認 - [6] ファイル存在が確認できれば指定のファイルの読み込む。逆の場合は読み込まない。
1. 全ページ共通で読み込むファイルの設定
app/assets/javascripts/application.js
には全ページ共通で必ず読み込んでおきたいファイルを列挙します。逆に言うと全ページ共通で必要ないファイルは記載しないようにします。
また自動でディレクトリ配下を読み込みしようとするrequire_tree
の記述は削除します
//= require jquery
//= require jquery_ujs
//= require turbolinks
2.コントローラ専用のAsset Pipeline対象ファイルの準備
次に今回の目的のひとつでもある各コントローラ専用のJavaScriptファイルの準備を行います。はじめに既存のjavascriptファイルと保存場所を区分けしたいのでコントローラ毎のjavascriptファイルを格納するディレクトリを作成しておきましょう。
$ mkdir app/assets/javascripts/controllers
そしてHogeController
というコントローラ専用のjavascriptファイルを以下のように作成します。
app/assets/javascripts/controllers/hoge.js
再度説明しますがhoge.js
にはHogeController
にアクセスした時にのみ実行させたいスクリプトを記載するファイルになります。
3. layouts/application.html.haml から現在アクセスしているコントローラパスをヘルパーに渡す
controller.controller_path
で現在アクセスしているコントローラ名・アクション名をヘルパーメソッドに渡します。
<%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %>
<%# 以下のif文を追記 %>
<% if controller_path_javascript_exists?("#{controller.controller_path}") %>
<%= javascript_include_tag "controllers/#{controller.controller_path}" %>
<% end %>
4. ヘルパーにAssetPipeline読み込み判定メソッドを追記
ヘルパー側では受け取ったコントローラパス名をもってFile.exists
にて該当のファイルが存在する確認する処理を行います。存在した場合はTRUE
が返ります。
module ApplicationHelper
def controller_path_javascript_exists?(script)
script = "#{Rails.root}/app/assets/javascripts/controllers/#{script}.js"
File.exists?(script) || File.exists?("#{script}.coffee")
end
end
controller.controller_path
がhoge/fuga
だった場合は、
app/assets/javascripts/controllers/hoge/fuga.js
のファイル存在を確認する処理が走り、存在した場合は、3.の javascript_include_tag
にてファイルの読み込みが行われる。という仕組みになります。
もちろんコントローラに沿ったファイルが存在しなかった場合は if 文の判定には入らないので全てのコントローラに対してJavaScriptファイルを用意する必要はありません。(ここがミソです)
5. AssetPipelineを行うファイルを指定する
ようやくここまでの処理を行った上で、基本的な準備が整いましたので、後はAssetPipelineを行いたい(コントローラに紐づく)ファイルをイニシャライザで指定します。
以下の3つのコントローラに対してAssetPipelineを指定する場合は
- controllers/hoge_controller.rb
- controllers/fuga_controller.rb
- controllers/hoge/fuga_controller.rb
Rails.application.config.assets.precompile += [/.*\.js/,/.*\.css/]
Rails.application.config.assets.precompile += %w('hoge.js')
Rails.application.config.assets.precompile += %w('fuga.js')
Rails.application.config.assets.precompile += %w('hoge/fuga.js')
のようになります。
6. サーバ再起動 & 動作確認
Railsサーバを再起動し、development環境にて動作確認を行います。
hoge.js
, fuga.js
, hoge/fuga.js
にそれぞれ任意のJSコードを記述して動作確認を行ってみて下さい。
また右クリックのソース表示を行い、コントローラに紐付いたファイルだけ読み込まれている事が確認できれば成功です。