Rails 4, Heroku doesn't recognize precompiled manifest-(fingerprint).json - heroku

After upgrading to Rails 4, public/assets/manifest.yml is not generated anymore. Instead the different formatted manifest-(fingerprint).json is present.
But it seems to me that the server is still looking for the old manifest.yml format, ignoring the .json version?
I see other questions based on similar problems, but they seems to be sovled by upgrading to Rails 4, adding rails_12factor to gem file, setting serve_static_assets = true, etc., but none of these solutions seems to have any effect in my scenario.
I am tired and uninspired due to this annoying problem, any help will be appreciated!
Logfile from Heroku:
ActionController::RoutingError (No route matches [GET] "/assets/layouts/test/test.html"):
Gemfile:
ruby '2.0.0'
gem 'rails', '4.0.0'
...
gem "compass-rails", github: "milgner/compass-rails", ref: "1749c06f15dc4b058427e7969810457213647fb8"
...
gem 'rails_12factor', group: :production
production.rb
RailsFoundationAngular::Application.configure do
config.assets.initialize_on_precompile = false
config.cache_classes = true
config.consider_all_requests_local = false
config.action_controller.perform_caching = true
config.serve_static_assets = true
config.assets.compress = true
config.assets.compile = false
config.assets.digest = true
config.i18n.fallbacks = true
config.active_support.deprecation = :notify
config.action_dispatch.x_sendfile_header = nil
end
I am using Angular and their ui-router, and this is the part of my routes.js.coffee where the test.html is linked:
.state "root",
url: "/"
views:
"root":
controller: "ApplicationController"
templateUrl: "/assets/layouts/test/test.html"
I have also tried precompiling locally, but as I am using Rails 4 here as well, still no manifest.yml is created, only the .json version.
Of course, everything is working just perfectly in development...
So my actual cuestion:
How do I make Heroku recognize and use the manifest-(fingerprint).json -file, or alternative ways to make this work?

The answer is, that Heroku already does recognize and use the manifest-(fingerprint).json -file. The "workaround" in my comment above, is the proper way to reference these files, and by doing so, the manifest-file is used the way it's ment to be used.
Renaming the file with the internal link to .erb, and referencing like this: templateUrl: "<%= asset_path('layouts/test/test.html') %>" does the trick. All internal files, images, and html -files should be referenced like this.
It's all described very thoroughly here: Asset-pipeline guide
It seems so simple and straightforward now, but I really spent a lot of time trying to get the wrong way around this from the beginning.
I hope this answer can save the time for someone else.

Related

Rails 4 assets not being served in production on Windows

I'm currently having the exact same problem as described in this post: Rails not serving assets in production or staging environments.
I am running Rails 4.0.4 in production environment on Windows 7 (so that could easily be the problem, can't use Linux unfortunately). I have run rake assets:clobber to make sure everything is cleaned up and and then RAILS_ENV=production rake assets:precompile and it succeeds without errors or warnings. All the files appear in my public/assets folder and using Windows explorer I can view the text in application.js and application.css, and images display correctly. However when I try to visit localhost:3001/assets/application.js it is blank, same with application.css, and image files come up with an error. I have restarted the server each time after changing settings and precompiling.
When I look at the logs it says the page renders successfully, there are no "No route matches" errors like I have seen in other posts. So the assets are being found, but for some reason they aren't being properly served.
Here is my production.rb:
ABC::Application.configure do
config.cache_classes = true
config.eager_load = true
config.consider_all_requests_local = false
config.action_controller.perform_caching = true
config.action_dispatch.x_sendfile_header = "X-Sendfile"
config.serve_static_assets = true
config.action_mailer.default_url_options = { :host => '' }
config.i18n.fallbacks = true
config.active_support.deprecation = :notify
config.assets.js_compressor = :uglifier
config.assets.css_compressor = :sass
config.assets.compile = false
config.assets.digest = true
end
Any help would be much appreciated, I've been stuck on this for nearly two days!
Just as I finished typing up this question, I finally came across another post which said the headers were being set but there was no body, which sounded like my problem. They were using nginx and fixed the problem by changing the following:
# Specifies the header that your server uses for sending files
# config.action_dispatch.x_sendfile_header = "X-Sendfile" # for apache
config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for nginx
And seeing as I'm not using either Apache or nginx, I commented out both lines and finally my assets were served. Seems obvious in hindsight but I thought I would post this anyway in case it helps anyone else having the same problem.

serving static files with Ruby Espresso

I'm trying to serve some assets using the el gem but can't seem to get it to work. I've referred to another question posted here -- Assets in espresso breaks my app
My setup looks like this --
require 'e'
require 'el'
...
app = E.new(true){
assets_url '/pub', true
}
But hitting localhost:5252/pub/hello.txt (yes, this file exists) results in 404. What am I missing?
You missed to append any paths to Sprockets environment.
http://espresso.github.io/Periphery/Assets.html#sprockets
Please try:
app = E.new(true){
assets_url '/pub', true
assets.append_path 'relative-path-to-static-files'
}

Heroku does NOT compile files under assets pipelines in Rails 4

Everything goes well in local machine with assets pipeline in Rails 4 and Ruby 2.0. But when deploying to heroku, it is shown that:
-----> Preparing app for Rails asset pipeline
Running: rake assets:precompile
I, [2013-03-12T03:28:29.908234 #912] INFO -- : Writing /tmp/build_1n6yi8lwna3sj/public/assets/rails-2ee5a98f26fbf8c6c461127da73c47eb.png
I, [2013-03-12T03:28:29.914096 #912] INFO -- : Writing /tmp/build_1n6yi8lwna3sj/public/assets/trash-3c3c2861eca3747315d712bcfc182902.png
I, [2013-03-12T03:28:33.963234 #912] INFO -- : Writing /tmp/build_1n6yi8lwna3sj/public/assets/application-bf2525bd32aa2a7068dbcfaa591b3874.js
I, [2013-03-12T03:28:40.362850 #912] INFO -- : Writing /tmp/build_1n6yi8lwna3sj/public/assets/application-13374a65f29a3b4cea6f8da2816ce7ff.css
Asset precompilation completed (14.36s)
Heroku seems to compile files but put it in /tmp without any errors. My questions are:
How come Heroku compile assets files to /tmp?
My last solution was to run RAILS_ENV=production bundle exec rake assets:precompile locally, but this generated a manifest-xxxxxx.json in public/assets, rather than manifest.yml, so that heroku doesn't detect the JSON manifest file. I sorted it out by manually created a yml from the json file and heroku became happy. Has heroku's approach been outdated?
Heroku's asset plugins no longer work since Rails 4 does not support plugins. You need to use Heroku's asset gems instead. Place this in your Gemfile:
group :production do
gem 'rails_log_stdout', github: 'heroku/rails_log_stdout'
gem 'rails3_serve_static_assets', github: 'heroku/rails3_serve_static_assets'
end
Follow Heroku's guide on getting started with Rails 4.
Update (07/22/2013): Heroku now supplies a different gem to precompile assets.
group :production do
gem 'rails_12factor'
end
You need to config Rails to serve static assets in production: config/environments/production.rb
SampleApp::Application.configure do
.
.
.
config.serve_static_assets = true
.
.
.
end
UPDATE:
In Rails 4 is deprecated, and has been changed by:
config.serve_static_files = true
Since rails 4 replaced manifest.yml with manifest-(fingerprint).json, you'll want to enable static asset serving.
From Getting Started with Rails 4.x on Heroku:
gem 'rails_12factor', group: :production
then
bundle install
and, finally,
git push heroku
Fixed the issue for me. Hope this helps!
I run exactly into the same problem.
I set config.serve_static_assets = true in my environments/production.rb file until heroku wont't support the new manifest format.
So it is a temporal solution until heroku support will be added.
After hours of googling in which none of the guides on Heroku or the suggestions on StackOverFlow helped me, I finally ran into this blog post which offered this clue:
heroku labs:enable user-env-compile --app=YOUR_APP
Without this, the asset pipeline will always try to init the whole app and connect to the database (despite all the things you may have read that rails 4 now longer does this). This exposes your Heroku configuration to Rails so it can boot up successfully and run rake tasks like assets:precompile.
I needed to use this gem:
gem 'rails_12factor', group: :production #need this for rails 4 assets on heroku
And in /config/environments/production.rb I needed to set:
config.assets.compile = true
My understanding is that the rails_12_factor gem sets config.serve_static_assets = true, amongst other things.
In my case, assets compiled following the instructions above but it wasn't picking the bootstrap glyphicons 'fontawesome-webfont' so this worked for me finally after wasting so many hours researching.
Gem file
gem 'rails_12factor', group: :production
bundle install
config/application.rb
config.assets.precompile += %w(*.png *.jpg *.jpeg *.gif,
"fontawesome-webfont.ttf",
"fontawesome-webfont.eot",
"fontawesome-webfont.svg",
"fontawesome-webfont.woff")
config.assets.precompile << Proc.new do |path|
if path =~ /\.(css|js)\z/
full_path = Rails.application.assets.resolve(path).to_path
app_assets_path = Rails.root.join('app', 'assets').to_path
if full_path.starts_with? app_assets_path
puts "including asset: " + full_path
true
else
puts "excluding asset: " + full_path
false
end
else
false
end
end
environment/production.rb
config.serve_static_assets = true
Then finally, I ran
rake assets:precompile RAILS_ENV=production and pushed it to heroku and that worked.
This was an issue with the Heroku Ruby Buildpack, but an update was deployed today (2013-05-21). Please try it out and let us know.
To answer your questions:
#1) This is sprockets output; things are compiled to /tmp and then moved (See here in Sprockets). To my knowledge this has always been done this way, but it wasn't until Sprockets version was updated in Rails that we got this new debug-type output.
#2) Previously assets:precompile genereated a manifest.json file, but now in Rails 4 the manifest file has a fingerprint in it, which wasn't detected previously. This was fixed with #74.
I added this to the top of one of my css.scss files in the assets/stylesheets/ folder.
#import "font-awesome";
then ran..
rake assets:clean
and...
rake assets:precompile RAILS_ENV=production
In Rails 4.2.4 your production.rb has the line:
config.serve_static_files = ENV['RAILS_SERVE_STATIC_FILES'].present?
That means, gem 'rails_12factor', group: :production doesn`t need to change it to true, as it can be set through the heroku environment variables. You also will get a warning if you remove the rails_12factor gem.
If you have problems with assets, login to the heroku console heroku run rails console and find out the asset path for a file puts helper.asset_path("application.js") .
One strange behaviour I noticed between development and production, when the file ending is not provided:
With a image /assets/images/image_01.jpg the following output from asset_pathsdiffers:
Development:
development > puts helper.asset_path('profile_01')
=> /assets/profile_01-bbd16aac5ef1d295411af44c103fcc631ab90ee94957414d4c01c3aed1055714.jpg
development > puts helper.asset_path('profile_01.jpg')
=> /assets/profile_01-bbd16aac5ef1d295411af44c103fcc631ab90ee94957414d4c01c3aed1055714.jpg
Production:
development > puts helper.asset_path('profile_01')
=> /profile_01
development > puts helper.asset_path('profile_01.jpg')
=> /assets/profile_01-bbd16aac5ef1d295411af44c103fcc631ab90ee94957414d4c01c3aed1055714.jpg
You do not have to run RAILS_ENV=production rake assets:precompile, heroku does this for you during deploy. Also you do not have to precompile the assets in development and push them to heroku.
Apart from ensuring you have the 'rails_12factor' gem installed the only thing you need to do is this.
# config/application.rb
config.assets.paths << Rails.root.join('vendor', 'assets')
It seems that although Rails knows exactly what it wants, Heroku needs reminding to include the assets folder as part of the assets paths.
Use Image Extensions
I had this same issue, but for a different reason.
Instead of
<%= asset_path 'facebook-link' %>
Use:
<%= asset_path 'facebook-link.png' %>
While the first one worked locally, when I pushed to Heroku my images were breaking and I had no clue why. Using the full file extension fixed the problem :)
Add this gem gem 'rails_serve_static_assets'
https://github.com/heroku/rails_serve_static_assets
If you are using controller specific assets as in:
<%= javascript_include_tag params[:controller] %> or <%= javascript_include_tag params[:controller] %>
Then in production you will need to explicitly precompile those (in development rails compiles files on the fly).
See official Rails guide here: http://guides.rubyonrails.org/asset_pipeline.html#controller-specific-assets
To precompile as explained in the guides (here: http://guides.rubyonrails.org/asset_pipeline.html#precompiling-assets) you will need to add the following to the config/application.rb
# config/application.rb
config.assets.precompile << Proc.new do |path|
if path =~ /\.(css|js)\z/
full_path = Rails.application.assets.resolve(path).to_path
app_assets_path = Rails.root.join('app', 'assets').to_path
if full_path.starts_with? app_assets_path
puts "including asset: " + full_path
true
else
puts "excluding asset: " + full_path
false
end
else
false
end
end
I figure I'll add this as an answer since this question is linked from the Heroku Support page if you search for "assets".
This is mostly for people who are updating their app to Rails 4, but after going through this - and many other SO posts - what finally got me was changing the following in production.rb:
config.action_dispatch.x_sendfile_header = "X-Sendfile"
To:
config.action_dispatch.x_sendfile_header = nil
I hadn't caught this when I upgraded and as usual this took me forever to figure out. Hopefully it helps someone else! Shout out to PatrickEm who asked/answered the same in his question.
This may not answer the original question's root cause, But I was having a similar symptom with a different root cause.
Pre-compilation of a JPEG files changes the file extension to JPG, meaning that asset_path("my_image.jpeg") and asset_path("my_image") didn't work. Remove the "e" from JPEG and voila, it works.
Others have described the same problem here https://blazarblogs.wordpress.com/2016/04/06/rails-force-to-precompile-jpeg-to-jpg/
Is this a bug? Or desired behaviour? And also weird that it only doesn't work in my Heroku-hosted production environment. Maybe they have some sort of configuration.

no route matches for assets/images in Rails

Working on rails, images are not visible and giving error.
Started GET "/assets/home.png" for 127.0.0.1 at 2012-06-19 12:23:24 +0530
Served asset /home.png - 404 Not Found (24ms)
ActionController::RoutingError (No route matches [GET] "/assets/home.png"):
I have used command
rake assets:precompile
production.rb
config.assets.compress = true
config.assets.compile = false
application.rb
config.assets.enabled = true
config.assets.version = '1.0'
Thanks for any help!
Actually you cannot reference your image with /assets/home.png path.
It will work in development mode, but in production all of your assets have a fingerprint in their filename (read this http://guides.rubyonrails.org/asset_pipeline.html#what-is-fingerprinting-and-why-should-i-care-questionmark)
That's why, in assets-pipeline enabled applications you need to reference all of your assets using helper methods. Read this doc to learn about the different helpers available in Ruby, JS and Sass files: http://guides.rubyonrails.org/asset_pipeline.html#coding-links-to-assets
The lack of a fingerprint in the file request suggests that you are running this in development. I am also going to guess that this is an app upgraded from an older version of Rails.
Any images need to be in the folder /assets/images for the pipeline to work.
Also, you do not need to precompile when in development mode.
Delete the public/assets folder, delete the folder tmp/cache/assets, and restart your server.
If this images are in the correct location, it should work.

Rails.3.1.1: config.assets.digest = true results in compiled css being used as a sprite's filename

I have a new-ish rails 3.1.1 app using sass/compass with compass taking care of the sprite generations for me. In development, all works just fine. However, when I deploy, I see this entry in the log file:
Compiled team/application.css (1ms) (pid 24202)
Compiled team/forms.css (0ms) (pid 24202)
Compiled team/member.css (0ms) (pid 24202)
Compiled application.css (0ms) (pid 24202)
Completed 500 Internal Server Error in 2014ms
ActionView::Template::Error (File name too long - /home/cri/webapps-releases/cri/releases/20111121225403/app/assets/images/html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote...(the rest of my compiled css goes here)
My production config (for asset stuff) is pretty vanilla wiht much of it being what was generated by rails:
# Disable Rails's static asset server (Apache or nginx will already do this)
config.serve_static_assets = false
# Compress JavaScripts and CSS
config.assets.compress = true
# Specify the default JavaScript compressor
config.assets.js_compressor = :uglifier
# Don't fallback to assets pipeline if a precompiled asset is missed
config.assets.compile = true
# Generate digests for assets URLs
config.assets.digest = true
config.assets.debug = true
Can anybody tell me why my compiled css is being used as the filename for the sprite?
Update: Modified title to reflect what I now think I know about this issue.
I am running rails-3.1.1 with sass-3.1.10 and sass-rails-3.1.5 and compass-0.11.3.
compass-0.11.3 does not have proper asset pipeline support you are going to want to be using the >= 0.12.alpha.3 release you can get this by doing gem install compass --pre if you are still having this issue under 0.12 then it is a bug and i would be grateful if you would file a ticket on the compass github.
Try
config.assets.debug = false
Those workarounds are true, but this bug in rails was fixed in 3.1.4. Upgrading is likely your best all-around bet.

Resources