I have a scenario where I want my CoffeeScript file to access an environment variable like an API key value. This works fine locally but it isn't working when I push it up to heroku.
The file is named something like myfile.js.coffee.erb
I am setting the value like this
api_key = '<%= ENV['SERVICE_API_KEY'] %>'
I know the values are set in heroku and I have triple checked the spelling, etc. I know it is being processed since the resulting JavaScript file looks like this
var api_key;
api_key = "";
Is there something I need to do when precompiling my assets where I can tell it to access environment variables? I admit that I am new to CoffeeScript and the Rails asset pipeline. Is there another more accepted way of doing this? I don't want to embed it in the file for obvious reasons.
So since the API key is going to be visible to those interested whether it's in the javascript file or the html file and since you really don't want to be generating a new .js file every request, the easiest solution I've found to the same problem is to put the key in your layout.html.erb file.
You can throw it in a script tag, use a data-attr, whatever floats your boat, but it works and you get the benefit of a dynamic variable and having to render one less file.
And you can still use the <%= ENV['api_key'] %>. You'll have to fetch the variable in your js (or coffee), but that's pretty trivial.
Try this
heroku labs:enable user_env_compile -a myapp
then deploy again
Worked for us!
all credits to this guy:
Heroku always runs assets:precompile with the production environment for Rails 3.2
Related
I need to iterate through multiple images via a JS file, so I am making an http request to the server to match the filename to its client-side fingerprinted equivalent. I'm getting the fingerprinted file by passing the original file through Rails.application.assets.find_asset(file).digest_path
Example, in the rails console:
Rails.application.assets.find_asset("scene1.jpg").digest_path
returns
"scene1-b691b411ad644bcf2c84ef9e30f52db9ffdf57c18fadf99872dff3ebb81fa548.jpg"
However, when I run on my local server the output is simply nil.
Using the Rails asset pipeline, assets are referenced with their logical path. In this case, you can use embedded ruby (erb) in your script by adding the .erb extension to the file, e.g.
var logo = <%= asset_path('logo.png') %>;
When this script is compiled, the ruby code will produce a reference to the asset with the current digest. The digest path is a "fingerprint" and will change as often as the assets themselves change.
To learn more about the asset pipeline, check out the ROR guide and the Sprockets documentation.
I have a css file in my public/assets/stylesheets/example.css directory. How can I access this css file directly from a url?
Ive tried www.app.com/assets/stylesheets/example.css but it doesnt work. I thought the public folder was the default folder in production? Im running rails 4 with passenger in a dedicated server (not heroku).
Please help! Thank you
IF you use assets procompilation you need to append the cacheing hash to the end of the filename (e.g. : application-03ed2f1b0877b3bc13330388bee8d3f0.css ) in addition, even if your project has more than one css, in production they will all end up into the same application-[...].css file. One option, other than updating the url every time you update your css, is to make a symlink to the css:
ln -s /var/www/myapp/app/assets/stylesheets/example.css /var/www/myapp/app/public/assets/external-example.css
EDIT:
also the url would be:
http://example.com/assets/application.css
not
http://example.com/assets/stylesheets/application.css
I clearly must be Doing Something Wrong here. I'm wrestling with the asset pipeline (again). I have a custom font, and it seems to me to get everything to compile properly I need to use asset_path() in multiple places, but it's having an unexpected effect.
I realize there are several ways to do this, but here's what I have currently:
In application.css.scss.erb:
#import "<%= asset_path("my-font.css") %>";
my-font.css's source file is app/assets/stylesheets/my-font.css.erb (it needs to be an .erb because I am also using asset_path() there as well).
In application.rb I am adding my-font.css to the precompile list.
config.assets.precompile << 'my-font.css'
When I clean out public/assets and run rake assets:precompile Everything's getting compiled, with digests, but the digest applied to the actual file is not the same as the digest calculated and put in to application.css.
The resulting file is
public/assets/my-font-2f25682a1ea904a866ef9f44101a5a2e.css but in public/assets/application-bba2edaee36771f4bdb5c89b8ec90aaf.css the reference to it is:
#import url(/assets/my-font-ed843d3b174ca427edf963e473ad9e9b.css);
I realize I'm probably using asset_path() more than I should, and also importing files via url() instead of requiring them, but this has gotten me the closest to having things working.
I suspect one of the digests is being calculated on my-font.css before it goes through ERB, and the other after, but I don't understand why nor how to fix it.
Suggestions?
I would guess that you're cleaning your assets just by emptying public/assets. That's not enough, you'll also need to empty your tmp/cache/assets, or just run rake assets:clobber to do both.
I've resolve this kind of dependency by injecting the raw contents of the asset you want to bundle into a composite asset like application.scss.erb. You need to explicitly declare the dependency (so that changes in my-fonts.css cause a regenerations of application.css) and then inject the contents:
application.scss.erb:
// Should be at Top of File
//= depend_on_asset my-fonts.css
//... wherever in the file you want the contents injected:
<%= environment['my-fonts.css'] %>
How does this work? During asset pipeline compilation, the environment here has a hash of all pre-compiled asset contents. This allows you to inject the compiled contents from my-fonts.css into your composite asset. Because we're manually injecting the value, we need to explicitly create a dependency to track this relationship via depend_on_asset.
One thing to keep in mind is that multiple asset pre-processors (SCSS, ERB, etc) are processed from the "outside in", so the contents of the my-fonts.css asset will be compiled/injected during the ERB processing as CSS output. They will be included within the asset before SCSS processing. This shouldn't pose a problem, because if this is an SCSS asset, any SCSS references will be compiled before injection into the parent asset.
I have an mp3 in <my root directory>/app/assets/sound. I want to be able to access this file from an html file, with the following:
<audio src="/assets/sound/mysong.mp3">
However the html5 audio player does not show up, and when I try to go to this link directly in my browser, I get an error:
Routing Error
No route matches [GET] "/assets/sound/mysong.mp3"
I've tried many variations on the URL, adding the sound directory to my config.assets.path, and setting config.serve_static_assets = true in my production.rb, and nothing is working. What is the fix for this?
Note that I don't require a high-performance server for this web page, so I don't want to handle static assets through Apache or anything else complicated. I just want a simple method for Rails to find a given file and return it.
One easy way to fix this would be to move the file to public/sound/mysong.mp3 and reference it by src="/sound/mysong.mp3". That should work fine, but does not use the asset pipeline.
Are we supposed to use something else aside from image-url and others in Rails 4? They return different values that don't seem to make sense. If I have logo.png in /app/assets/images/logo.png and I do the following, this is what I get:
image-url("logo.png") -> url("/images/logo.png") #obviously doesn't work
image-path("logo.png") -> "/images/logo.png"
asset-url("logo.png") -> url("/logo.png")
Of course none of these work because they need at least /assets in front.
UPDATE: Actually, I just noticed, how do I access images in Rails 4? I have an image at /app/assets/images/logo.png. But if I go to any of the following URLs, I still don't see my image:
http://localhost:3000/assets/logo.png
http://localhost:3000/assets/images/logo.png
http://localhost:3000/logo.png
http://localhost:3000/images/logo.png
UPDATE 2: The only way I can bring up my logo.png is by moving it into the /app/assets/stylesheets directory and then pulling up:
http://localhost:3000/assets/logo.png
I just had this issue myself.
3 points that will hopefully help:
If you place images in your app/assets/images directory, then you should be able to call the image directly with no prefix in the path. ie. image_url('logo.png')
Depending on where you use the asset will depend on the method. If you are using it as a background-image: property, then your line of code should be background-image: image-url('logo.png'). This works for both less and sass stylesheets. If you are using it inline in the view, then you will need to use the built in image_tag helper in rails to output your image. Once again, no prefixing <%= image_tag 'logo.png' %>
Lastly, if you are precompiling your assets, run rake assets:precompile to generate your assets, or rake assets:precompile RAILS_ENV=production for production, otherwise, your production environment will not have the fingerprinted assets when loading the page.
Also for those commands in point 3 you will need to prefix them with bundle exec if you are running bundler.
Your first formulation, image_url('logo.png'), is correct. If the image is found, it will generate the path /assets/logo.png (plus a hash in production). However, if Rails cannot find the image that you named, it will fall back to /images/logo.png.
The next question is: why isn't Rails finding your image? If you put it in app/assets/images/logo.png, then you should be able to access it by going to http://localhost:3000/assets/logo.png.
If that works, but your CSS isn't updating, you may need to clear the cache. Delete tmp/cache/assets from your project directory and restart the server (webrick, etc.).
If that fails, you can also try just using background-image: url(logo.png); That will cause your CSS to look for files with the same relative path (which in this case is /assets).
I just found out, that by using asset_url helper you solve that problem.
asset_url("backgrounds/pattern.png", image)
I had a similar problem, trying to add a background image with inline css. No need to specify the images folder due to the way asset sync works.
This worked for me:
background-image: url('/assets/image.jpg');
Rails 4.0.0 will look image defined with image-url in same directory structure with your css file.
For example, if your css in assets/stylesheets/main.css.scss, image-url('logo.png') becomes url(/assets/logo.png).
If you move your css file to assets/stylesheets/cpanel/main.css.scss, image-url('logo.png') becomes /assets/cpanel/logo.png.
If you want to use image directly under assets/images directory, you can use asset-url('logo.png')
for stylesheets:
url(asset_path('image.jpg'))
In case anyone arrives looking for how to generate a relative path from the rails console
ActionView::Helpers::AssetTagHelper
image_path('my_image.png')
=> "/images/my_image.png"
Or the controller
include ActionView::Helpers::AssetTagHelper
image_path('my_image.png')
=> "/images/my_image.png"