自宅サーバーにdeployment
TweetWatchがとりあえず完成したので、自鯖(Apatch)で動かしてみたらjQueryの一部(画面描画時$(document).ready()
の処理だけ)が上手く動かなかったので動くようになったまでの顛末を書きます(Rails 4.0.2, ruby 2.0.0p353)。
コードは以下の通りです
#app/assets/javascripts/users.js
$(document).ready(function(){
$.ajax({
url: '/tweets/check',
data: {},
dataType: "script"
}).done(function(data, status, xhr) {
}).fail(function(xhr, status, error) {
alert('Error Occured(' + error + ')');
});
});
処理の内容はあまり関係ないと思いますが、jQueryからcontrollerのメソッドを呼び出し、サーバースクリプトが動いているかどうかをチェックして画面にstatusを表示する処理をしています。このusers.jsがdevelopment環境では動くのにproduction環境では動かないという現象に悩まされました。動くようになるまでに辿った作業を順に箇条書きにしてみると以下のようになります。
1. Apache+Passenger環境でうまく動かないので、以下の設定でwebrickでproduction環境を試す。特にwebrick用の設定とも言える
serve_static_assets = true
がdevelopment環境との大きな違い-
#config/environments/production.rb config.assets.compile = false config.assets.js_compressor = :uglifier config.serve_static_assets = true config.assets.digest = true config.assets.debug = true
rake assets:precompile RAILS_ENV=production
rails s -e production
2. 変化が無かったのでjquery-turbolinks gemを追加してみる
-
#Gemfile gem 'jquery-turbolinks' <- 追加
bundle install
#app/assets/javascripts/application.js //= require jquery //= require jquery_ujs //= require bootstrap //= require users.js //= require turbolinks //= require jquery.turbolinks <- 追加 //= require highcharts/highcharts //= require highcharts/highcharts-more //= require highcharts/highstock //= require_tree .
※<a href=https://github.com/kossnocorp/jquery.turbolinks/blob/master/README.md>jquery-turbolinksのドキュメント</a>rake assets:precompile RAILS_ENV=production
rails s -e production
3. jquery-turbolinks gemを追加してもダメだったので、今度は逆にturbolinksを無効にしてみる
-
#Gemfile # gem 'turbolinks' <- コメント化 # gem 'jquery-turbolinks' <- コメント化
#app/assets/javascripts/application.js //= require jquery //= require jquery_ujs //= require bootstrap //= require users.js //= require turbolinks <- この行を削除 //= require jquery.turbolinks <- この行を削除 //= require highcharts/highcharts //= require highcharts/highcharts-more //= require highcharts/highstock //= require_tree .
bundle install
#app/views/layouts/application.html.erb #変更前 <%= stylesheet_link_tag "application", media: "all", "data-turbolinks-track" => true %> <%= javascript_include_tag "application", "data-turbolinks-track" => true %> #変更後 <%= stylesheet_link_tag "application", media: "all" %> <%= javascript_include_tag "application" %>
rake assets:precompile RAILS_ENV=production
rails s -e production
4. turbolinksは関係なかったので、関係ないと思ったけど今度はcoffee scriptに変えてみる
-
jqueryとturbolinks両イベント対応の書き方
jqueryイベントとturbolinksイベントを分けた書き方#app/assets/javascripts/user.js.coffee $(document).on 'ready page:load', -> url = '/tweets/check' dfd = $.ajax url: url format: 'script' data: {} method: 'get' promise = dfd.promise() promise.done((data, status, xhr) -> ) promise.fail((xhr, status, error) -> alert(error) )
#app/assets/javascripts/user.js.coffee ready = -> url = '/tweets/check' dfd = $.ajax url: url format: 'script' data: {} method: 'get' promise = dfd.promise() promise.done((data, status, xhr) -> ) promise.fail((xhr, status, error) -> alert(error) ) $(document).ready(ready) $(document).on('page:load', ready)
rake assets:precompile RAILS_ENV=production
rails s -e production
5. どっちのcoffee scriptでもダメなので、こんどは正常に動作しているdevelopment環境の設定をproduction環境と同じにして確認。
-
#config/environments/development.rb config.assets.compile = false config.assets.js_compressor = :uglifier config.serve_static_assets = true config.assets.digest = true
デフォルトでは書かれていない上記設定をdevelopment環境の設定ファイルに追加して
rails s -e development
すると、めでたく?production環境と同じくページload時のjqueryだけが発動しない現象が再現しました。結局config.assets.compileがtrueかfalseかで動作が変わるようです。念のためdevelopment環境でconfig.assets.compileの値だけを書き換えて現象の発生の有無を確認しました。
でも本番(production)環境でconfig.assets.compile = trueにして運用することは、重くなるので普通はしないと思いますし、結局config.assets.compile = falseのままではturbolinksの有効・無効に関係なく、このjqueryを発動させることは出来ませんでした。 6. 何か方法はないかとテンプレートファイルに直接jqueryを直書きしてみたところ
-
#app/views/users/show.html.erb <%= javascript_tag do %> $(document).ready(function(){ $.ajax({ url: '/tweets/check', data: {}, dataType: "script" }).done(function(data, status, xhr) { }).fail(function(xhr, status, error) { alert('Error Occured(' + error + ')'); }); }); <% end %>
これでdevelopment環境でもproduction環境でもページ読み込み時のjqueryが正常に動作しました。
config.assets.compile = falseでdevelopment,production両方の環境で動きます。いろいろ環境を弄りましたが元の環境からjqueryをテンプレートに直書きするように変えるだけで他は変更しなくてよかったみたいです。turbolinksが有効でも無効でも大丈夫です
結論
「$document.readyイベントを使うjqueryが動作しない時は、テンプレートに直書きしてみる。」
※ネットの情報を漁っていると、jquery-turbolinks gemを使えば解決するというものが多いのですが、document.readyイベントに関してはそういうわけにはいかないようです。