I am currently using Rails 4.0.2 with jQuery UI (mostly for the datepicker). My production environment is Heroku.
My main problem is that the images for my theme are not being served in production (while it works fine in development). I am including the theme's css like this in my application.css:
*= require_self
*= require_tree .
*= require jquery-ui-1.10.4.custom
The theme's css is showing up fine, but none of the images are working. I have read through endless questions on StackOverflow, blogs and discussions on Github - none of which have worked for me. I also read through the Edge Rails guide which doesn't mention a word about image precompilation, even though from the discussions on Github it seems that this has really changed in Rails 4.
Here is my current directory structure:
/vendor
/assets
/stylesheets
jquery-ui-1.10.4.custom.css
/images
animated-overlay.gif
ui-bg_flat_0_aaaaaa_40x100.png
(more images like these)
As far as I know the correct way of integrating external css and javascript libraries is to put those assets inside /vendor/assets so that is what I'm doing.
So again, my problem is that rails flatly refuses to serve any assets in production. I can fiddle with the image URL, but it's simply not getting served.
Here are things I have tried:
Force Rails 4 to precompile images
If I run rake assets:precompile I only see 2 files inside public/assets - a css file and a javascript file. I'm assuming this is wrong and that Rails should actually put my images there as well.
According to this question - rails 4 asset pipeline vendor assets images are not being precompiled - you need to explicitly tell Rails that you want images to be precompiled. (This seems rather insane to me, since I am pretty sure I am not the only Rails 4 site on the internet serving images. Is everyone else just using text and ASCII art?)
So I added this to my application.rb:
config.assets.precompile += %w(*.png *.jpg *.jpeg *.gif)
Now when I run rake assets:precompile all my vendor assets are being compiled, fingerprinted and put in public/assets/images. This has no effect in production though, I suspect that Rails is simply refusing to serve the default assets and will only serve the fingerprinted assets.
Manually include the vendor images path
Some of the other things I read suggested that you need to manually specify the images path if it is outside of app/assets (since mine is in vendor/assets this seems to qualify).
config.assets.paths << Rails.root.join('vendor', 'assets', 'stylesheets', 'images')
When I now run rake assets:precompile my images are no longer being precompiled or fingerprinted, but they are also not being served in production.
According to this blog post - JQuery-UI css and images, and Rails Asset Pipeline - this is because Sprockets will see that a path is already included and will exclude it and you can fix it by prepending the path in application.rb.
initializer :after_append_asset_paths,
:group => :all,
:after => :append_assets_path do
config.assets.paths.unshift Rails.root.join("vendor", "assets", "stylesheets", "images").to_s
end
This also had no effect. When I run rake assets:precompile it doesn't compile or fingerprint my images and it doesn't show up in production. That post is targeted at Rails 3 so I didn't really have high hopes.
Move all images to app/assets/images
Even though this seems wrong to me (in the Rails sense) I moved all the images to app/assets/images. This still had the same result - images are not showing up in production. I also tried combining this with the trick of forcing images to be included in compilation:
config.assets.precompile += %w(*.png *.jpg *.jpeg *.gif)
But it didn't have any effect. I suspect Rails is simply being stubborn and not serving the non-fingerprinted assets.
Other things I have tried
The images being requested are done via css, so if I look in the actual theme's css file there are lines like this:
background: #aaaaaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x;
Some things I read (mostly in the comments/complaints on Github and blog posts) suggested that the /images at the beginning of the url is screwing with me. So I manually went into the file and removed it everywhere, which had no effect - meaning images still didn't show up in production.
Things I don't want to try
According to this post - Rails 4: How To Fix The Heroku Assets Not Found CSS Image Issue - I should add this to my production.rb
config.assets.compile = true
I really don't want to do that since the asset pipeline does it by default and according to my knowledge (which might be completely wrong) it would be really bad for performance. For the same reason I don't want to just go ahead and add
config.serve_static_assets = false
to my production.rb since I don't want Rails serving static assets in production - I want Apache/nginx to do it.
How are you supposed to do this in Rails 4? Please help!
I finally managed to fix this issue. There are 2 parts to the solution. Firstly, you need to tell Rails to precompile images. As far as I can tell Rails (since 4.0) will no longer do this automatically to prevent gems you include from having all their assets precompiled when you don't really want this.
config.assets.precompile += %w(*.png *.jpg *.jpeg *.gif)
Now your images should be getting precompiled (you can check this by running rake assets:precompile and looking at the results in public/assets).
Now you need to change your JQuery UI theme to reference the fingerprinted images instead of the plain image URL. So change the theme's filename extension to .scss (in my case it was jquery-ui-1.10.4.custom.css.scss) and do a find and replace in your theme - changing url to the SASS helper image-url. So, as an example,
url(images/ui-bg_glass_65_ffffff_1x400.png)
becomes
image-url('images/ui-bg_glass_65_ffffff_1x400.png')
Related
Found a strange bug in Ruby on Rails 4.1 asset pipeline on Heroku. All of my PNG images are not being compiled.
In Development:
image_tag('icons/example.png')
# => "/assets/icons/example-09adfasdfa7sfhpasodfuahsdas.png"
In Production on Heroku
image_tag('icons/example.png')
# => "/images/icons/example.png"
I have never run across anything like this in the asset pipeline. Any ideas as to why?
Update
As it turns out, it's not PNG images in particular. It is any image accessed via image_tag. Any images that are precompiled in CSS and Javascript point to the proper paths, but any views/helpers that use image_tag (and thus path_to_image) are pointing to the /images. I cannot tell if this has to do with the serve_static_assets configuration that Heroku recommends that is not playing well with Rails 4.1
This is an app that I am upgrading to Rails 3.1, along with the asset pipeline. Everything looks peachy in development, but when I push to heroku, the images in my css are not displaying.
Couple of questions. First, should I leave these files with the css extention, or should they be renamed to either scss, or css.scss.erb?
The other question I have is how should I reference images in the css. Currently I have...
background: #B4F4FF url(/assets/img01.jpg) repeat-x left top;^M
I am pretty sure I need to replace url with either 'image_tag' or 'asset_tag'...looks like there are a few options available. Also, what should the path be?...../assets, assets/images, just the file name???
I've tried all manner of methods, and paths, and can't get this to work in Heroku. Any help appreciated!
Wow! This was a real pain to figure out.
For me the issue centered around static pages that I had in my app. I had to add the line...
config.assets.precompile += ['static_pages.css']
to config/environments/production.rb, then compile my assets locally with
RAILS_ENV=production bundle exec rake assets:precompile
then push all that to heroku.
I was running into issues with Heroku showing my 'places.js' was not precompiled, even though im running on the cedar stack, and during the slug compilation it is running the rake precompile task. so i tried running it locally with rake assets:precompile RAILS_ENV=production and indeed rails was not precompiling my /app/assets/javascripts/places.js.coffee.erb asset.
my production.rb is using default rails 3.1 configuration, and i even tried removing the .erb from the asset, but to no avail.
I also thought since my places.js.coffee.erb asset is NOT included in the sprockets manifest (i include it manually in my app), perhaps it only precompiles assets in the manifest. Requiring it in the manifest didn't work either.
only my application.js.coffee and `application.css are precompiling (with and without a digest).
the only issue i found was possibly poor regex being used to match assets, but the default of (?:\/|\\|\A)application\.(css|js)$ does not match my asset, so it should be included.
i am not sure how to troubleshoot from here. everything is pretty much default. any thoughts on what could be happening here?
Firstly, if you want a file to compile when it is not in a manifest, you need to add it to the precompile config option:
config.assets.precompile += ['places.js']
Secondly, can you edit your question to include your manifest - it may be a syntax issue. I will edit this answer if I can see what the issue might be.
I had the same issue and resolved it like this:
# add new file /app/assets/javascripts/places_manifest.js
//= require places
# add a line to config/application.rb
config.assets.precompile += ['places_manifest.js']
# in your views include places_manifest, not places
javascript_include_tag 'places_manifest'
While the above solutions seem fine, I wondered why do I have to do this?
Like everyone else, I got the error in production stating that my newly added javascript file was not pre-compiled. It was however, I found it's code in the minified application.css file that Rails had generated on my production server.
The problem was that while developing, I thought I would need to add a javascript_include_tag helper to load my new javascript file. Adding that helper was the source of my particular error. I just removed it, and everything worked fine in both development and production environments.
So my suggestion to you is look for signs of your new .js file in your minified application.js and don't modify any other files as the above solutions suggest. Please point out the error in my ways if necessary ;)
I am having trouble trying to rake assets:precompile in my rails 3.1 app. I keep getting the following error:
rake aborted!
Invalid CSS after "...und-image: url(": expected ")", was "<%= asset_path(..."
It seems that the erb preprocessor is not being invokeb but my file is called style.css.scss.erb. Any suggestions?
Ruby documentation seems a bit unclear on a few things such as the usage of the asset_path and other such helper in stylesheets. Anyways this is what I did to get around the exact same problem:
I decided to do this the SASS-way by changing my stylesheet extensions from css to scss.
The image references in my code were changed from
background-image: url(<%= asset_path 'blah.png' %>);
to
background-image: image-url("blah.png");
I found the necessary documentation on the sass helpers on one of the RailsGuides
I've also added the config.assets.digest = true line to my config/appliction.rb file because that seemed to get my output HTML to refer to the hashed filenames. Without the digest flag set to true I get all of my link tags starting off with <link href="/assets/print.css?body=1" ... or <href="/assets/favicon.png"... which pretty much defies the purpose of using the assets pipeline. Especially the favicon file will still be cached by the servers and CDN's along the way.Explicitely setting the digest flag to true gets me <link href="/assets/print-e47f5a48af04ce6854c840d74cd28fba.css?body=1" and <link href="/assets/favicon-15fb5e00d868940bc32db7996e10f594.png" ...
Change the file extension from
xxx.scss.css
to
xxx.scss.css.erb
and everything shoule be fine
Even though an answer has already been accepted, and my specific solution may not have solved the OP's issue, this question was the top google hit so thought this might help someone else. I couldn't accept the idea of having to change all my stylesheets to use the SASS-style asset paths instead of ERB-style, because ERB should work. After some digging, I realized that I had so many files with embedded ruby asset_path helpers, and I had missed one in the app/assets/stylesheets directory that still had just a .css extension (forgot to add .erb). Also, I was including vendor.css, and that included one other file in vendor/assets/stylesheets that needed the .erb. Finally, I was using an older version of svn which still used the .svn directories at every level of the hierarchy, and since I had a 'require_tree .' in application.css, the .svn-base files may have been getting compiled as well, and obviously wouldn't be run through the erb processor. Fixing all the above got me working again.
This is a sass-rails error, as discussed here.
I had the same question and found out that the solution is by installing sass-rais-path.
This gets Rails to work SASS + ERB as expected, even though you may continue using the asset_path helper.
The new rails 3.1 asset pipeline confused me a lot. In rails 3.0.x, with the sass gem, my global css file got updated when I edit .scss files. But in rails 3.1, that doesn't work anymore. It seems like I have to run a rake task to update my css files whenever I modify the .scss files. I feel like I misunderstand something about the new asset pipeline, but I don't know what it is. Can someone provide a solution or explanation to this problem? Thank you.
There are two possible causes of this. I am assuming that you are in development mode, and that all the gems are loaded.
1. Config
In development mode files are compiled on-demand and cached until any changes are made. You have to get the new 3.1 config options set in the right files or this might not work as expected.
Check out the Rails guides section on upgrading.
2. Extensions
The other is getting the extensions in the right order. For scss that would be file.css.scss. This tells Sprockets to parse the files as scss first, and that the have a css extension. If you had .erb on the end - file.css.scss.erb - then erb is processed first, then scss.
Upgrading apps is a bit tricky because so many things have changed. The asset pipeline guide has lots of useful information and advice.
Sass / SCSS has this built in already so you don't have to do ERB pre-processing.
image-url("image.png")
http://guides.rubyonrails.org/asset_pipeline.html#coding-links-to-assets
For me this problem resolved very easy.
I simple deleted all precompiled *.css files from assets/stylesheets and remain all *.scss files. Rails worked fine with *.scss directly, withoutn precompile.