All JS files inside / assets / javascript are part of the asset pipeline. During production, the resource pipeline is compiled in advance when the Rails application is deployed (for example, not for every request). This is why @s3_direct_post.url is zero.
I agree that injecting all of the JS code in a view is less than ideal and not very elegant. I used to come up with approaches based on JS infrastructures such as Google Analytics, where only 2-3 JS lines are placed in HTML:
window.MyApp = {}; window.MyApp.config = {}; window.MyApp.config.getS3Url = function() { if(typeof(window.MyApp.config._s3Url) == 'undefined') { throw "No S3 URL configured"; } return window.MyApp.config._s3Url; }; window.MyApp.config.setS3Url = function(url) { window.MyApp.config._s3Url = url; }
Then, in the view, you only need to reference the Config API you created:
<script type="text/javascript"> window.MyApp.config.setS3Url('<%= @s3_direct_post.url %>'); </script>
However, if you are really determined not to have JS in the views. You can load configurations through a dynamic JSON request:
class JSConfigsController < ApplicationController def index configs = { 's3URl' => @s3_direct_post.url # etc } respond_to do |f| f.json do render json: {config: configs} # => {"config": {"s3Url": "http://the_url"}} end end end end
Then you can download all the configs via ajax by requesting /js_configs.json . However, this approach requires a bit more caution due to the asynchronous nature of Ajax. For example, you should be careful not to call JS functions that rely on configurations until an Ajax request is received.
Pete
source share