We're upgrading our app from Rails 2 to Rails 3.1, and I'm having trouble with the asset pipeline.
I've got the following in my config/application.rb:
if defined?(Bundler)
Bundler.require *Rails.groups(:assets => %w(development test))
# Bundler.require(:default, :assets, Rails.env)
end
# Enable the asset pipeline
config.assets.enabled = true
# config.assets.prefix = "/assets"
config.assets.paths << "#{Rails.root}/public/images"
config.assets.paths << "#{Rails.root}/public/stylesheets"
config.assets.paths << "#{Rails.root}/public/javascripts"
config.assets.version = '1.0'
And then this in development.rb
# Do not compress assets
config.assets.compress = false
config.assets.debug = true
I know this isn't the desired behavior for the pipeline, but we are doing it this way to make sure that when we merge the upgrade back into our master branch, all the old files are accounted for properly.
I then have the following file, "all.css," in my public/stylesheets directory:
/*
*= require ezform
*= require jquery-ui-1.8.9.custom
*= require thickbox
*= require yui-upload
*= require styles
*/
I am calling it from within my layouts/application.html.erb file like so:
<%= stylesheet_link_tag "all" %>
Loading things up in a browser, however, I get no styles (or javascript, for that matter). Firebug and Chrome tell me that the .css and .js files are being looked for in "/assets" - it's like the pipeline isn't searching through everything and bundling it like it should.
The error looks like this:
GET http://localhost:3000/assets/jquery-dependent.js 500 (Internal Server Error)
If I move "all.css" into /app/assets, it still won't find it. Moving it into /assets stops the error, but the stylesheet doesn't compile and I still don't get any styles in my browser.
There's also a slew of errors that look like this in my log:
Started GET "/assets/defaults.js?body=1" for 127.0.0.1 at 2011-12-22 14:35:36 -0600
[2011-12-22 14:35:36] ERROR NoMethodError: You have a nil object when you didn't expect it!
You might have expected an instance of Array.
The error occurred while evaluating nil.each
/Users/kevin/.rvm/gems/ruby-1.9.2-p0#media3/gems/rack-1.3.5/lib/rack/handler/webrick.rb:71:in `service'
/Users/kevin/.rvm/rubies/ruby-1.9.2-p0/lib/ruby/1.9.1/webrick/httpserver.rb:111:in `service'
/Users/kevin/.rvm/rubies/ruby-1.9.2-p0/lib/ruby/1.9.1/webrick/httpserver.rb:70:in `run'
/Users/kevin/.rvm/rubies/ruby-1.9.2-p0/lib/ruby/1.9.1/webrick/server.rb:183:in `block in start_thread'
cache: [GET /assets/defaults.js?body=1] miss, store
Served asset /defaults.js - 200 OK (1ms)
What am I missing?
sigh It was memcached. I tured it on (memcached -d) and now all my assets are appearing. I'm not sure why, so I'd love some explanation. Otherwise, it's working.
There are a while bunch of settings that need to be added into the development and application config files for the pipeline to work correctly.
Check out the last section of the pipeline guide for details of these.
Once you've done that I suggest that you change the manifest names to application.css and application.js as these are the default names and you'll run into fewer problems starting with those. Edit your question if it still does not work and I'll see if I can help after that.
Related
I've got 3 Rails 3.2 applications using the gem jquery-ui-themes. jquery-ui-themes uses scss for the image-path helper.
It works great on two of my applications, but the 3rd doesn't seem to compile the scss files in either development or production modes.
IOW, it sends this to the browser
background: #fcfdfd url(image-path("jquery-ui/redmond/ui-bg_inset-hard_100_fcfdfd_1x100.png")) 50% bottom repeat-x;
whereas the two working apps properly send
background: #fcfdfd url("/assets/jquery-ui/redmond/ui-bg_inset-hard_100_fcfdfd_1x100.png") 50% bottom repeat-x;
I've spent many hours trying to make the app that's broken as similar to possible to the two working apps as I can, but it's still failing.
My theory is that SASS is choking on something previous to redmond.css.scss. If so, there should be an error logged somewhere. Where do I find the error output from SASS?
Update:
I introduced a deliberate error into redmond.css.scss and I got a proper error dump. So I know that I'm correctly clearing the cache and actually running sass. Now to figure out why it's ignoring the image-path directives.
If you're looking for the answer to the question in the title, the answer is "the same way you get any other errors: they're in your log". To get a full backtrace, just point your browser at the asset: ie http://localhost:3000/assets/jquery-ui/redmond.css in my case.
Make sure you clear all your caches: rm -rf .sass-cache/ && rm -rf public/assets && rake tmp:cache:clear, as well as using ctrl-shift-r in your browser.
If you're looking for the answer for my real problem (image-path not working), make sure you have the proper Bundler.require line in your application.rb. The old Rails 3.0 doesn't work.
replace:
# If you have a Gemfile, require the gems listed there, including any gems
# you've limited to :test, :development, or :production.
Bundler.require(:default, Rails.env) if defined?(Bundler)
with:
if defined?(Bundler)
# If you precompile assets before deploying to production, use this line
Bundler.require(*Rails.groups(:assets => %w(development test)))
# If you want your assets lazily compiled in production, use this line
# Bundler.require(:default, :assets, Rails.env)
end
So I have a file jquery.tmpl.min.js sitting under app/assets/javascripts/ and for whatever reason it's not being found in my production server. After runnings rake assets:precompile it completes without any errors whatsoever. All my other javascript assets get compiled properly and sent to the browser. I don't have any issues on my development server finding this JS file.
I have the following lines in my production.rb file:
config.serve_static_assets = true
config.assets.compile = true
config.assets.precompile += %w( *.js *.css )
Error message:
ActionController::RoutingError (No route matches [GET] "/assets/jquery.tmpl.min.js"):
Edit
According to this issue: https://github.com/rails/rails/issues/3596
Using the javascript_include_tag with something like 'jquery.ba-url.min' wont append the .js extension. Originally I had that but have since changed it to include the .js extension. Still no dice however.
Edit 2
I tried adding //= require jquery.tmpl.min.js to my application.js but now when I attempt to precompile my assets it says it can't find the file.
Edit 3
Tried adding //= require_tree and still it isn't found. This is driving me nuts!
Ok, I found the answer. It turns out Edit 2 was the fix that I was looking for. Problem was that I made the edit on development and commited to my production server using github. However I forgot to add the renamed file to the commit so all my commit ended up doing was deleting the file on the production server.
I changed a JS file under app/assets/javascripts but it is still the same. I deleted the file and re-created but the content is still the old one. This is my development.rb file:
App::Application.configure do
# Settings specified here will take precedence over those in config/application.rb
config.serve_static_assets = false
# In the development environment your application's code is reloaded on
# every request. This slows down response time but is perfect for development
# since you don't have to restart the web server when you make code changes.
config.cache_classes = false
# Log error messages when you accidentally call methods on nil.
config.whiny_nils = true
# Show full error reports and disable caching
config.consider_all_requests_local = true
config.action_controller.perform_caching = false
# Don't care if the mailer can't send
config.action_mailer.raise_delivery_errors = false
# Print deprecation notices to the Rails logger
config.active_support.deprecation = :log
# Only use best-standards-support built into browsers
config.action_dispatch.best_standards_support = :builtin
# Do not compress assets
config.assets.compress = false
# Expands the lines which load the assets
config.assets.debug = true
config.action_mailer.delivery_method = :letter_opener
config.action_mailer.default_url_options = { :host => "lvh.me:3000" }
# Raise exception on mass assignment protection for Active Record models
# config.active_record.mass_assignment_sanitizer = :strict
# Log the query plan for queries taking more than this (works
# with SQLite, MySQL, and PostgreSQL)
config.active_record.auto_explain_threshold_in_seconds = 0.5
config.log_tags = [:uuid, :remote_ip]
end
The JS file is loaded inside the header tag with this code:
<script src="/assets/deals.js?body=1" type="text/javascript"></script>
which is the normal way JS is loaded in development
Try to clear precompiled assets:
bundle exec rake assets:clean
Try to delete the tmp folder and then restart the server - rails s.
That will do it.
bundle exec rake assets:clean and then bundle exec rake assets:precompile
Or delete the public/assets folder, and restart the app
Check for sprockets-rails gem
In my case I upgraded to Rails 7, and for some reason, the javascript files were not updated. Spent many hours trying to work out why.
I finally discovered the culprit - in my case - somehow, I had removed the sprockets-rails gem. I could have easily lost many months trying to figure this out.
I have similar issue in my app running Rails 6 and 7. When I add console.log into one of the javascript controllers there won't be any log in the browser console, and it looks like the console.log is not even there.
I have been having issue for quite some time and have not been able to pinpoint the exact reason, it might be due to bundler installed globally, conflict between rvm and asdf, config for overmind, yarn or npm. But I found the 3 commands that resolve this problem for some time and I usually run them one after another
rails assets:clobber
rake tmp:cache:clear
rake assets:precompile
Currently working on a project where we need to drop in various static html pages + static assets for those from time to time that "just work." We cannot have anyone editing the html directly to place paths in for the assets. We need it to simply work such that the html + asset folders are placed directly into /public and the content is served up as it was generated.
When testing this behavior in production, it's a no go with errors such as:
ActionController::RoutingError (No route matches [GET] "/some_folder/some-image.png"):
I assume this is a result from what I'm reading from 3.1.x's asset pipeline.
How do you alter the routes such that these will be served up directly? Or is there a preferred way to keep this precise behavior? (Ultimately this will be deployed on heroku.)
Adding some more details as current remarks have not yet pushed my issue over the edge in terms of a solution:
In my present scenario I'm running it straight on WEBrick rails s -e production to test it out. In development mode this does work properly; the only exception is in production.
I am also running this prior to running the server:
bundle exec rake RAILS_ENV=production RAILS_GROUPS=assets assets:precompile --trace
When I actually attempt to load the page in production, I see the following output:
cache: [GET /] miss
cache: [GET /test_files/index.css] miss
cache: [GET /test_files/index.js] miss
cache: [GET /test_files/logo.png] miss
cache: [GET /test_files/background.png] miss
cache: [GET /test_files/horizontal.png] miss
cache: [GET /favicon.ico] miss
Upon further scrutiny of the production.rb I am seeing: "config.serve_static_assets = true" that when set to false by default evokes the issue experienced in webrick. So when setting that to true it serves the files up properly.
From some additional reading it appears that perhaps Heroku needs this set to false as well, which is the environment to which we're deploying.
Thanks for the input, but this appears to be the approach to take for now and I'd certainly appreciate any further input if this is NOT the correct answer or if there's a better approach.
As of Rails 3.1.1 the precompile task creates non-digested as well as digested filenames, so you can refer to these in static files (while still having the digest version in dynamic files).
The only problem is if you use far-future headers on the assets directory; changes to the undigested files won't be pick up by remote clients that still have a copy and believe the cache to still be valid.
You may need to look at an approach the replaces the non-digested filenames with the correct name during the deployment process.
If you do not use far-future headers in the directory then it does not matter - you can use either name.
For me the #ylluminate's answer helped: I've changed the config.serve_static_assets option to true in the config/environments/production.rb file and restarted the server with
$rails server --environment=production
and now it serves compressed assets.
NOTE: I've also precompiled the assets with
$bundle exec rake assets:precompile
(call rake this way assure will be used the rake version choosen for the project but I guess use just rake assets:precompile will work 99% of the times)
If you have /public/some_folder/some-image.png physically present (no matter if you just copied it there manually or it was generated by assets precompile), it must work. The server (e.g. Apache) will first check if the requested path exists in public, if it does it won't even call Ruby on Rails.
As far as digested filenames are concerned there is an option to turn this feature off, but I wouldn't recommend that for reasons already mentioned by someone else here.
Also you can put files that refer to assets in the app/assets folder and add a .erb extension AT THE END. Then you can use <%= asset_path ... %> inside that file, so no manual editing will be necessary. This will work even if you already have some other preprocessing on the file, for example sass - style.css.scss.erb will work. First the erb code will be evaluated (putting in the correct filenames for assets) then the sass compiler will be ran.
Oh and have a look at the sprockets-image-compressor gem, just add it to your Gemfile and it will automagically compress image assets too (losslessly using pngcrush and jpegoptim)...I don't know if the gem is rock-solid but from what I've seen I love it!
I have a rails application I would like to use for multiple sites, each with different designs.
I would like to change the rails installation /public directory to something else (dynamically eventually). However, I have run into a problem (bug?) changing directories...
In my application.rb file I change the paths.public path to something other than "public" (let's say "site_one"). Here is the code:
puts paths.public.paths
paths.public = "site_one"
puts paths.public.paths
The two "puts" commands are for debugging. Now run "rails s" and you will see:
/home/macklin/app/public
/home/macklin/app/site_one
This verifies the path is changed correctly. However, shortly afterward, rails throws the following error (let me know if you need the full trace):
Exiting
/usr/lib/ruby/gems/1.8/gems/railties-3.0.3/lib/rails/paths.rb:16:in `method_missing': undefined method `javascripts' for #<Rails::Paths::Path:0x7f422bd76f58> (NoMethodError) from /usr/lib/ruby/gems/1.8/gems/actionpack-3.0.3/lib/action_controller/railtie.rb:47
My guess is it cannot find the javascripts directory even though it is clearly sitting in the "site_one" folder.
Does anyone know why I am getting this?
I know this question is pretty old, but I think I found an answer for this in Rails 4.2.
You just simply have to put this line in your config/application.rb:
middleware.use ::ActionDispatch::Static, "#{Rails.root}/another_public_folder_name", index: 'index', headers: config.static_cache_control
This makes all files in /another_public_folder_name to be served by Rails.
This is the way Rails use to setup the standard /public folder. I found it checking the sources:
https://github.com/rails/rails/blob/52ce6ece8c8f74064bb64e0a0b1ddd83092718e1/railties/lib/rails/application/default_middleware_stack.rb#L24
Duh. Just add 2 more rules for stylesheets and javascripts (I guess they get wiped when you change the parent path)
paths.public.stylesheets = "site_one/stylesheets"
paths.public.javascripts = "site_one/javascripts"