Why won't Rails find my assets? - asset-pipeline

When in production mode, rails can't seem to find any precompiled assets from the asset pipeline.
I'm using rails 3.2.0 and ruby 1.9.3 running inside RVM on CentOS. No additional web server is running in conjunction with this application. The application was only recently updated to use the asset pipeline, as it was originally a rails 3.0 app.
After running
rake assets:clean
rake assets:precompile
I see the hashed content in public/assets, as I would expect. The hashes at the end of the files match those I see in the page source.
Yet at runtime, here's what I see for every asset Rails tries to serve:
Started GET "/assets/application-892c6227e631daf9a8e041b1d4d002ec.css" for 75.149.58.169 at 2012-03-14 11:42:43 -0700
ActionController::RoutingError (No route matches [GET] "/assets/application-892c6227e631daf9a8e041b1d4d002ec.css"):
I'm not referring to the folder that each asset is housed in; all references to assets look like these:
//css:
.class {
background: url(asset.png) no-repeat;
}
//erb:
<%= image_tag "asset.png" %>
<%= link_to "page", :class => "class" %>
Asset pipeline pertinent settings in production.rb:
config.serve_static_assets = false
config.assets.enabled = true
config.assets.compress = true
config.assets.debug = false
config.assets.compile = false
config.assets.digest = true
And lastly, asset settings from config/application.rb:
config.assets.enabled = true
config.assets.version = '1.0'
The user starting the rails server process has read, write and execute permissions on public/assets, so I don't think it's a permissions issue. Have I missed a configuration step?
Edit
I noticed that there are no errors stating that assets are not precompiled, so I tried to access a stylesheet from the web page by appending"/assets/application-892c6227e631daf9a8e041b1d4d002ec.css" to the end of the host path:
http://www.myapp.com"/assets/application-892c6227e631daf9a8e041b1d4d002ec.css"
This worked and the stylesheet opened.

Further researching of this issue yielded this SO article:
application.css not being served as an asset
It seems
config.serve_static_assets = false
Is an incorrect setting as long as my Rails application is not running behind Apache or nginx

I had this same problem, but I note that your stylesheet is pointing to the non-fingerprinted, non-cached version of the files. If you are using the asset pipeline, in order to take advantage of it, you need to use the helpers that point to the fingerprinted, cached version of the files. To do this, you'll need to either embed erb in your css file, or use sass.
Incorrect:
.class {
background: url(asset.png) no-repeat;
}
Correct (uses sass):
.class
background: image-url('asset.png') no-repeat
For more info, see here: http://guides.rubyonrails.org/asset_pipeline.html#coding-links-to-assets
If you don't care about the performance issues, you can get away with using the non-cached versions until you upgrade to Rails 4 or Rails 3.2.16, because those versions introduce breaking changes that force you to use the asset pipeline (and its corresponding syntax). If you don't use the new syntax, the non-cached versions will not work at all on production.

Related

Ruby on Raills disabling the Assets-Pipeline

I try to update an old rails application.
It was original written with rails 2.3 and works now with rails 5.0.7
It does not use the asset pipeline, as there is not much css and js, and think it would make updating even more complex.
When trying to update to Rails 5.1, it seem now to wanting to use the asset pipeline, and throws errors:
<%= stylesheet_link_tag 'stylesheetfile.css' %>
ActionView::Template::Error (The asset "stylesheetfile.css" is not present in the asset pipeline.
):
I have already tried the following in application.rb
config.assets.enabled = false

Rails 4 - Asset fingerprints spontaneously go missing from asset paths

Configuration: Rails 4, HTML, CSS, on Heroku.
I have a Rails 4 app that has been in production for five months. Here's what's in my production.rb:
config.serve_static_assets = false
# Do not fallback to assets pipeline if a precompiled asset is missed.
config.assets.compile = false
# Generate digests for assets URLs.
config.assets.digest = true
config.assets.enabled = true
config.assets.initialize_on_precompile = true
config.action_controller.asset_host = "//dynasfakeurl.cloudfront.net"
Whenever I push to production, I clean my assets using rake assets:clean, then precompile them using rake assets:precompile. This fingerprints my assets, and pushes it directly to my S3 static file bucket, which are served via cloudfront. I then push my app live to Heroku.
On the .html.erb homepage, I call my static files via Rails tags like this:
<%= image_tag "picture.png" %>
<%= stylesheet_link_tag "application" %>
Which render correctly using fingerprints. For example, the second one most recently generated this asset path: http://dynasfakeurl.cloudfront.net/assets/application-17892abdffc77f1fb1be125bab.css
Usually, this works great. However, I've had a problem, twice now, where after 12-16 hours of my last push, all of my asset paths spontaneously lose their fingerprints. For example, the stylesheet tag last generated this asset path: http://dynasfakeurl.cloudfront.net/stylesheets/application.css. Which doesn't exist. Thus, when I load the page, it fails to load the assets.
I've been stuck for the past few hours trying to debug this, but can't figure out why my asset paths would spontaneously, without me pushing anything, lose their fingerprints in production.

AWS to serve CSS images Sinatra

I am using the asset_sync gem to sync my assets to a S3 bucket. In production i want to use S3 and in development i want to use my local files. So i have setup the following along with a helper
environments/development.rb
configure :development do
set :asset_host, "/"
end
environments/production.rb
configure :production do
set :asset_host, "https://s3-eu-west-1.amazonaws.com/#{ENV['FOG_DIRECTORY']}"
end
helper
helpers do
def aws_asset( path )
File.join settings.asset_host, path
end
end
So in my views i can do this
<%= image_tag( aws_asset "/assets/images/wd.png") %>
Which will result in rendering that image from my local assets if in development or from my bucket when in production
So what if i want to render an image from within my main.css file, such as a background image? I cant do the below for example as its not an erb file
main.css
header{
background: #ffffff url('<%= aws_asset("/assets/images/bgwRpeat.png") %>') repeat-x;
}
So what can I do? Has anyone done this before
Thanks for any help anyone can offer
3 ways come to mind.
Precompile the assets
Before you deploy, precompile the assets and CSS. If you create a file called main.css.erb and then run it through ERB to produce main.css it'll have the right stuff inside. This would be my preference. There are lots of ways to precompile, I prefer Guard but YMMV.
Edit:
Lifted and twisted from the Guard::Erb docs
guard 'erb', :input => 'app/views/stylesheets/main.css.erb', :output => "public/assets/stylesheets/main.css" do
watch (%r{app/views/stylesheets/main.css.erb})
end
Something like that.
Create a route that then compiles the assets
This is similar to how you might use SASS templates with Sinatra (if you don't precompile them). Just do the same as above, set up a route for main.css, run the main.css.erb template through ERB and serve it. Add lots of caching.
Edit:
get "/assets/stylesheets/main.css" do
# remember to look at caching
erb :"stylesheets/main.css"
end
I started writing and I can't remember the 3rd :) In my defence, I've a terrible headache. Perhaps someone else will remember for me.

Rails 3.1 - How to separate CSS/JS between normal app and active_admin gem

My application is deployed on Rails 3.1 and on Heroku.
1. In production.rb, if I have config.assets.compile = true only then active_admin works. However, in production, I want config.assets.compile = false for normal application CSS and JS. The active admin module will be used only by administrator so it can be slow.
2. Moreover, since I installed active_admin gem my normal CSS has got terribly disturbed.
Hence, I want to somehow split the CSS and JS of active_admin and normal application so that:
1. Only when I hit localhost:3000/admin then CSS and JS of active admin hits and that of normal app does not. When I am on any other URL, then CSS and JS of normal app hits but active admin's does not.
2. I can config.assets.compile = false to normal app CSS and JS while make it config.assets.compile = true for active_admin alone.
Is this possible?
The good news is that you can have .compile set to false for both, and have both run fast!
Active admin uses its own manifests that start with 'active_admin'. By default these won't be precompiled by Rails.
To get them precompiled you need to add these files to the precompile array in production.rb:
config.assets.precompile += ['active_admin.js', 'active_admin.css']
This will create the files in the /assets folder and allow you to set .compile to false all the time.
Don't forget to also set:
config.assets.digest = true

Rails 3.1 assets not recognizing new images uploaded by rmagick until server restart

I have my Rails 3.1.0 application running with passenger in production environment and I have a section where the application allows the user to change his profile picture so I upload the image using an ajax uploader and in my controller I upload the file and generate different sizes for the image with rmagick then I render the new image with an image_tag but the application won't show the image till I restart the server.
What I get is No route matches [GET] "assets/path/to/image.png"
If I restart the server It will show the image, but obviously I can't be restarting the server every once a user uploads a new image.
How can I solve the keeping the assets working the right way?
The Rails asset pipeline is really meant for structural / design images, such as backgrounds, icons, banners, etc..). Dynamic assets should go in the public directory [source below]
It's probably a good idea to serve static assets through Nginx or Apache or whatever your web-server is, or place them in the public directory of your Rails app.
That should solve your problem right there.. e.g. make a separate path for static assets into which you upload those images with rmagick / carrierwave, or whatever gem you prefer.
The asset pipeline only knows about images which are present during start-up. So separating static / uploaded assets into a separate directory , and serving it directly through the web-server, will help -- it should also be much faster.
you'll need something like this in your configuration:
# 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
# Don't fallback to assets pipeline if a precompiled asset is missed
config.assets.compile = false
# Generate digests for assets URLs
config.assets.digest = true
# UNCOMMENT 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
More General:
http://railscasts.com/episodes/279-understanding-the-asset-pipeline
http://guides.rubyonrails.org/asset_pipeline.html
Rails 3.1: Should File Uploads be added to asset pipeline?
Regarding serving images outside asset pipeline:
http://mrjaba.posterous.com/rails-31-asset-pipeline-with-nginx-and-passen
http://trackingrails.com/posts/rails-31-and-asset-pipeline-problems-with-apache
http://pastebin.com/kC4Ba40U
https://github.com/defunkt/resque/issues/418

Resources