Question

I have a js.erb file in my Rails app that will be included as an external script by another site. I would like to define a variable that stores the absolute URL of the Rails asset path (protocol + host + asset prefix) such that the URLs look something like this:

Dev

var absURL = "http://localhost:3000/assets/";

Staging

var absURL = "http://staging.foo.com/assets/";

Prod

var absURL = "http://foo.com/assets/";

I'm not quite sure how to do this—the request object isn't available here and the asset path helpers are only returning paths relative to the root.

Some suggestions have been to pass the URL to the script or render the JS on an endpoint so that the root_url is available. Ideally, there is a solution for the above, but I'm open to other ideas.

Edit: I did see this question. I'm basically attempting the same thing however, I would like to avoid adding specific environment variables.

Thanks in advance!

Was it helpful?

Solution

Ok, now that I understand your question, I'll answer according....

First option:

Edit your files:

  • config/environments/development.rb
  • config/environments/test.rb
  • config/environments/production.rb

and you have to write the host like:

default_url_options[:host] = 'www.example.com'

then you can create a javascript within your assets like app/assets/javascript/test.js.erb, make sure to add the .erb extension so ruby code is executed first when compiling the javascript and add the code:

<% environment.context_class.instance_eval { include Rails.application.routes.url_helpers } %>
var absURL = '<%= root_url %>';

Have in mind that because its an asset, it will be precompile when deploying once, and the minified version will be served for every request (so the ruby code will be executed just when deploying).


Option 2:

you can add a route of your choice in config/routes.rb like:

match 'my_js', to: 'home#my_js'

and then you can create a view in your home controller: app/views/home/my_js.js.rb and add the ruby code right there:

var absURL = '<%= root_url %>';

Be sure to include the actionpack-page_caching gem in order to generate a cache for your action, so it gets compiled on first request and then it will just serve the compiled version on all the other requests (although it won't minify the javascript, so the assets may be a better solution)

OTHER TIPS

First in your view set hostURL variable

#application.html.erb
<script>
   window.hostURL = "<%=j request.original_url %>";
</script>

And now you can use hostURL variable inside a javascript file but before using the variable make sure DOM is loaded

#script.js
$(document).ready(function() {
  var absURL = host_url + 'assets/';
  alert(absURL);
})

I hope this helps

Edit

Also take a look at gon gem https://github.com/gazay/gon , you might find it helpful.

You can define the variable in your view before including the javascript file:

<%= javascript_tag("var absURL = '#{root_url}';") %>

Then on your javascript file, you will have the variable absURL, you can check by trying on your js file:

$(document).ready(function() {
  alert(absURL);
});
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top