Rails - Loading assets through the Asset Pipeline - ruby-on-rails

I am trying to set up asset pipeline on a older rails app that i have so that i can start using CoffeeScript. i am using ruby 1.9.3-p327 and Rails 3.2.13. I used to stash all my JS, CSS and my images in the public/ folder. This is what i have done so far ->
I moved them all to app/assets, i added the manifest files for both JS and CSS call //= require_tree ..
Added the following gems
group :assets do
gem 'coffee-rails'
gem 'uglifier'
gem 'sass-rails'
gem 'therubyracer'
end
Removed all my javascript_include_tags except for = javascript_include_tag 'https://ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js'
Added the following to my config/application.rb file
# Enforce whitelist mode for mass assignment.
# This will create an empty whitelist of attributes available for mass-assignment for all models
# in your app. As such, your models will need to explicitly whitelist or blacklist accessible
# parameters by using an attr_accessible or attr_protected declaration.
config.active_record.whitelist_attributes = true
# Enable the asset pipeline
config.assets.enabled = true
# Version of your assets, change this if you want to expire all your assets
config.assets.version = '1.0'
Within the config/environments/development.rb file set
# Do not compress assets
config.assets.compress = false
# Expands the lines which load the assets
config.assets.debug = true
I added to the config/environments/production.rb
# Compress JavaScripts and CSS
config.assets.compress = true
# Choose the compressors to use
# config.assets.js_compressor = :uglifier
# config.assets.css_compressor = :yui
# 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
# Precompile additional assets (application.js, application.css, and all non-JS/CSS are already added)
# config.assets.precompile += %w( search.js )
I re-read the section on the Asset Pipeline just to see if i messed up anything. But so far none of the assets are pulling through from app/assets the only one that is working is the jquery.min.js that i have coming in through include_tag i have tried removing it and trying again no dice.
I have tried bundle exec rake assets:clean, and bundle exec rake assets:precompile, both of which run without issues. and have bundled since adding the gems for the assets, and restarted pow each time.
I am not sure if i am going through this all wrong or i have missed a step? any one gone through this before and tips or clues would be much appreciated.

You said you removed all the javascript_include_tag statements. Assuming you named the manifests app/assets/javascripts/application.js and app/assets/stylesheets/application.css, you'll need to include those in your layout:
<%= stylesheet_link_tag "application", :media => "all" %>
<%= javascript_include_tag "application" %>
Otherwise, Rails won't know to load your manifest files
Also, you shouldn't be using rake assets:precompile in development. If you do, then anytime you change a JS/CSS file, you'll have to recompile the assets before your changes show up.

Related

Rails 5.2 asset helpers not including fingerprint digests

I am in the process of upgrading our product from rails 4.1 to 5.2. I'm hung up on what appears to be an asset pipeline related issue. When I load the app in our browser, I see the following error in the server log and the app is missing all styling and javascript code that it normally has.
DEPRECATION WARNING: The asset application.js" is not present in the asset pipeline.Falling back to an asset that may be in the public folder.
This behavior is deprecated and will be removed.
To bypass the asset pipeline and preserve this behavior,
use the `skip_pipeline: true` option.
When I wget the index.html of the application, I see that all of the images and javascript urls are lacking the fingerprint digest they should have. Interestingly enough, they do have the S3 asset_host we have, so they are in fact being processed by the helpers.
To demonstrate, I have two servers which have identical configurations, but one is running 4.1 and the other 5.2. On both, I am using S3 as an asset_host and digest is turned on. I've run the following commands in their consoles:
=== Rails 4 ===
Loading qatest environment (Rails 4.1.0)
irb(main):001:0> Rails.application.config.action_controller.asset_host
=> "https://redacted.s3.amazonaws.com"
irb(main):002:0> Rails.application.config.assets.digest
=> true
irb(main):003:0> ActionController::Base.helpers.asset_path('application.js')
=> "https://redacted.s3.amazonaws.com/assets/application-042f2014ca329c79c304ab1332557040d3f7b922247202f40c28acc950f30ef8.js"
=== Rails 5 ===
Loading sean environment (Rails 5.2.1)
irb(main):001:0> Rails.application.config.action_controller.asset_host
=> "https://redacted.s3.amazonaws.com"
irb(main):002:0> Rails.application.config.assets.digest
=> true
irb(main):003:0> ActionController::Base.helpers.asset_path('application.js')
=> "https://redacted.s3.amazonaws.com/application.js
As requested, production.rb
require "#{File.dirname(__FILE__)}/includes/s3_assets"
Rails.application.configure do
# Settings specified here will take precedence over those in config/application.rb
config.eager_load = true
# 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 = false
config.log_level = ENV['SHOW_SQL'] != 'false' ? :debug : :info
# Show full error reports and disable caching
config.consider_all_requests_local = true
config.action_controller.perform_caching = false
config.action_mailer.raise_delivery_errors = true
config.action_mailer.perform_deliveries = true
config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {
user_name: Rubber.config.email_username,
password: Rubber.config.email_password,
address: Rubber.config.email_server,
port: Rubber.config.email_port,
enable_starttls_auto: true, # detects and uses STARTTLS
authentication: 'login' # Mandrill supports 'plain' or 'login'
}
# 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
# 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
# Compress JavaScripts and CSS
config.assets.compress = true
# Don't fall back to assets pipelin if a precompiled asset is
# missed.
config.assets.compile = false
# Generate digests for assets URLs
config.assets.digest = true
config.assets.enabled = true
# Nginx will serve as an asset proxy to s3, where assets are
# stored.
config.serve_static_assets = false
# instead of bundling the assets, include multiple css style includes
config.assets.debug = true
config.assets.logger = false
# Enable serving of images, stylesheets, and JavaScripts from an asset server
# NB: The exclusion of any protocol in the asset host declaration above will allow browsers to choose the transport mechanism on the fly.
# So if your application is available under both HTTP and HTTPS the assets will be served to match.
configure_s3_assets config
config.action_controller.asset_host = "https://#{Rubber.config.s3_assets_bucket}.s3.amazonaws.com"
config.action_mailer.default_url_options = { :host => Rubber.config.external_host }
config.sequel.search_path = %w(public audit)
end
config/initializers/assets.rb
# Be sure to restart your server when you modify this file.
# Version of your assets, change this if you want to expire all your assets.
Rails.application.config.assets.version = '1.0'
# Add additional assets to the asset load path
# Rails.application.config.assets.paths << Emoji.images_path
# Precompile additional assets.
# application.js, application.css, and all non-JS/CSS in app/assets folder are already added.
# Rails.application.config.assets.precompile += %w( search.js )
Rails.application.config.assets.precompile += %w( *.js *.png *.eot *.woff *.ttf *.svg *.gif)
config/environments/includes/s3_assets.rb
def configure_s3_assets(config)
# Do not compress assets
config.assets.compress = false
# Disable Rails's static asset server (Apache or nginx will already do this)
config.serve_static_assets = false
# Generate digests for assets URLs
config.assets.digest = true
config.assets.enabled = true
# Precompile additional assets (application.js, application.css, and all non-JS/CSS are already added)
config.assets.precompile += %w(
)
# find javascripts/ stylesheets/ -type f | sed 's/\.scss//' | sed 's/\.coffee//' |
# sed 's/^.*\/\///'| sort
# defaults to application.js, application.css
# application.css has home.css ?
config.assets.precompile += %w(
handlebars.js
jquery-1.7.js
json2.js
)
end
After digging around in the sprockets code, I discovered that my list of resolvers was empty. I'm not sure what was missing from my configuration, but I fixed the problem by adding the following to config/application.rb
config.assets.resolve_with = [:manifest] // in production
config.assets.resolve_with = [:manifest, :environment] // in development

Rails 4: assets on Heroku

I have deployed my app to heroku, but some assets are not loading, e.g.:
GET https://myapp.herokuapp.com/javascripts/s3_direct_upload.js - 404
GET https://myapp.herokuapp.com/stylesheets/s3_direct_upload_progress_bars.css - 404
the problem is in precompile, I have to add every file manually to assets.rb
but I don't really want to do it, because there are many of them
in my assets.rb I tried:
Rails.application.config.assets.precompile << Proc.new { |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
}
and:
Rails.application.config.assets.precompile = false
but it's not working
I've added to application.rb
config.serve_static_files = true
also, //=require from my precompilled assets are not included into header
everything works good in dev environment on my laptop
what do I need to change to make it work in production?
Update
I use helper, to include some js and css files in views:
def javascript(*files)
content_for(:foot) { javascript_include_tag(*files) }
end
and in my view I have:
<% stylesheet 's3_direct_upload_progress_bars' %>
<% javascript 's3_direct_upload', 'init.script.js' %>
assets from gem s3_direct_upload are not loading
init.script.js is located in assets/javascripts, so it is loading as it should be
another problem, in my application.js I have:
//= require jquery
//= require jquery.slicknav.min.js
$(function ()
{
$('#menu').slicknav();
});
after assets:precompile it looks okay, but in console I have error:
$(...).slicknav is not a function
so it was compiled wrong? everything works good in development environment
Update 2
Ignore the second problem, I found second require for jquery, it caused this error
but I still can't include assets from gem without precompile,
can I somehow disable this behavior? I just want include some assets for specific actions without headache
By default Rails 4 will not serve your assets. To enable this functionality you need to go into config/application.rb and add this line:
config.serve_static_assets = true
Alternatively you can achieve the same result by including the rails_12factor gem in your Gemfile:
gem 'rails_12factor', group: :production
This gem will configure your application to serve static assets so that you do not need to do this manually in a config file.
Hope this will work for you.

Rails asset paths missing fingerprint in production

We've just deployed a Rails 4.0.3 app to production and have found that asset paths generated by stylesheet_link_tag and javascript_link_tag are missing their fingerprints. So instead of requesting something like application-c841bd1c82c25bb1de8452d2338479f7.js, the page is just request application.js.
RAILS_ENV=production bundle exec rake assets:precompile is successful and generates fingerprinted files.
The bits from config/environments/production.rb that seem relevant are:
# 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
# Disable Rails's static asset server (Apache or nginx will already do this)
config.serve_static_assets = false
This is running on our own Apache server, not Heroku. I've looked around quite a bit and found similar problems, but none of the troubleshooting steps for those are helping here. Thanks.
More Information
In case it is helpful, here are the full contents (commented lines removed) of our config files:
application.rb
require File.expand_path('../boot', __FILE__)
require 'rails/all'
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
module Ctrc
class Application < Rails::Application
config.ceal.application_title = "CTRC Budgeting"
config.encoding = "utf-8"
config.filter_parameters += [:password]
config.active_support.escape_html_entities_in_json = true
config.assets.enabled = true
config.assets.version = '1.0'
config.pmacs_redmine.project_identifier = 'itmat-gcrc'
config.app_data_path = '/data/web/apps/itmat/ctrc'
config.paperclip_defaults = {
path: "/data/web/apps/itmat/ctrc/:attachment/:id/:style/:basename.:extension"
}
if ENV['RAILS_RELATIVE_URL_ROOT']
config.assets.prefix = ENV['RAILS_RELATIVE_URL_ROOT'] + '/assets'
end
end
end
production.rb
Ctrc::Application.configure do
config.cache_classes = true
config.consider_all_requests_local = false
config.action_controller.perform_caching = true
config.serve_static_assets = false
config.assets.compress = true
config.assets.compile = false
config.assets.digest = true
config.i18n.fallbacks = true
config.active_support.deprecation = :notify
config.eager_load = true
end
I know that the application is running in production mode because if I set
config.assets.compile = true
in that file, the CSS and JavaScript are compiled and requested correctly.
I'm including those assets in the page like so:
<%= stylesheet_link_tag "application", media: "all" %>
<%= javascript_include_tag "application" %>
but it is still generating links to those assets like this:
<link href="/apps/itmat/ctrc/stylesheets/application.css" media="all" rel="stylesheet">
<script src="/apps/itmat/ctrc/javascripts/application.js"></script>
instead of the fingerprinted links I would expect to see.
I had a similar issue and it turned out to be a problem with the gem AssetSync. Either setting config.assets.compile = true or removing the gem resolved the issue. Compiling assets on the fly and having your Rails serve your assets might be acceptable if you're using a CDN, but generally, taking another approach is usually recommended.
For rails 4.x be sure to set the following:
config/application.rb
config.assets.enabled = true
config.assets.version = '1.0'
config/environments/production.rb
config.assets.compile = false

rake assets:precompile is slow in production

My ruby on rails app take about half an hour to complete a deployment.
The longest step is
RAILS_ENV=production RAILS_GROUPS=assets bundle exec rake assets:precompile
which takes about 1073155ms
I have to wait for a long time for each deployment.
I use
ckeditor
rails_admin
I guess it is them who slow down my deployment, but I don't evidence and I don't know how to
solve it, either.
My other environments are as follows:
rails 4.0.3
ruby 2.1.1
My production.rb about assets is
config.serve_static_assets = false
# Compress JavaScripts and CSS.
config.assets.js_compressor = :uglifier
# config.assets.css_compressor = :sass
# Do not fallback to assets pipeline if a precompiled asset is missed.
config.assets.compile = true
# Generate digests for assets URLs.
config.assets.digest = true
# Version of your assets, change this if you want to expire all your assets.
config.assets.version = '1.0'
Try to skip compiling ckeditor assets
config/environments/production.rb
require_relative '../../lib/assets/selective_assets_compressor'
config.assets.js_compressor = SelectiveAssetsCompressor.new
lib/assets/selective_assets_compressor.rb
class SelectiveAssetsCompressor < Uglifier
def initialize(options = {})
super(options)
end
def compress(string)
if string =~ /CKSource/
string
else
super(string)
end
end
end
For faster asset precompiles, you can setting config.assets.initialize_on_precompile to false in config/application.rb. Heroku requires this to be false.
config.assets.initialize_on_precompile = false
If you do that, be sure to test rake assets:precompile locally because the complete environment is not loaded, engines (or other gems) will not be loaded, which can cause missing assets.
In the other hand you can execute asset precompile before deploy locally and deploy the files precompiled.

rails 3.1.0 ActionView::Template::Error (application.css isn't precompiled)

I made a basic rails app with a simple pages controller with an index function and when I load the page I get:
ActionView::Template::Error (application.css isn't precompiled):
2: <html>
3: <head>
4: <title>Demo</title>
5: <%= stylesheet_link_tag "application" %>
6: <%= javascript_include_tag "application" %>
7: <%= csrf_meta_tags %>
8: </head>
app/views/layouts/application.html.erb:5:in `_app_views_layouts_application_html_erb__43625033_88530400'
Gemfile
source 'http://rubygems.org'
gem 'rails', '3.1.0'
# Bundle edge Rails instead:
# gem 'rails', :git => 'git://github.com/rails/rails.git'
gem 'sqlite3'
gem 'execjs'
gem 'therubyracer'
# Gems used only for assets and not required
# in production environments by default.
group :assets do
gem 'sass-rails', " ~> 3.1.0"
gem 'coffee-rails', "~> 3.1.0"
gem 'uglifier'
end
gem 'jquery-rails'
# Use unicorn as the web server
# gem 'unicorn'
# Deploy with Capistrano
# gem 'capistrano'
# To use debugger
# gem 'ruby-debug19', :require => 'ruby-debug'
group :test do
# Pretty printed test output
gem 'turn', :require => false
end
By default Rails assumes that you have your files precompiled in the production environment, if you want use live compiling (compile your assets during runtime) in production you must set the config.assets.compile to true.
# config/environments/production.rb
...
config.assets.compile = true
...
You can use this option to fallback to Sprockets when you are using precompiled assets but there are any missing precompiled files.
If config.assets.compile option is set to false and there are missing precompiled files you will get an "AssetNoPrecompiledError" indicating the name of the missing file.
You will get better performance in production if you set config.assets.compile to false in production.rb and precompile your assets. You can precompile with this rake task:
bundle exec rake assets:precompile
If you are using Capistrano, version 2.8.0 has a recipe to handle this at deploy time. For more info, see the "In Production" section of the Asset Pipeline Guide:
http://guides.rubyonrails.org/asset_pipeline.html
OK - I had the same problem. I didn't want to use "config.assets.compile = true" - I had to add all of my .css files to the list in config/environments/production.rb:
config.assets.precompile += %w( carts.css )
Then I had to create (and later delete) tmp/restart.txt
I consistently used the stylesheet_link_tag helper, so I found all the extra css files I needed to add with:
find . \( -type f -o -type l \) -exec grep stylesheet_link_tag {} /dev/null \;
A quick fix for capistrano user is to put this line to Capfile
# Uncomment if you are using Rails' asset pipeline
load 'deploy/assets'
For all those who are reading this but do not have problem with application.css and instead with their custom CSS classes e.g. admin.css, base.css etc.
Solution is to use as mentioned
bundle exec rake assets:precompile
And in stylesheets references just reference application.css
<%= stylesheet_link_tag "application", :media => "all" %>
Since assets pipeline will precompile all of your stylesheets in application.css. This also happens in development so using any other references is wrong when using assets pipeline.
I was having the exact same error in my development environment. In the end all I needed to do in order to fix it was to add:
config.assets.manifest = Rails.root.join("public/assets")
to my config/environments/development.rb file and it fixed it. My final config in development related to assets looks like:
config.assets.compress = false
config.assets.precompile += %w[bootstrap-alerts.js] #Lots of other space separated files
config.assets.compile = false
config.assets.digest = true
config.assets.manifest = Rails.root.join("public/assets")
config.assets.debug = true
I also had this issue, where trying to run in production without precompiling it would still throw not-precompiled errors. I had to change which line was commented application.rb:
# 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)
Here's the quick fix:
If you're using capistrano do this add this to your deploy.rb:
after 'deploy:update_code' do
run "cd #{release_path}; RAILS_ENV=production rake assets:precompile"
end
cap deploy
I ran into this error message today and wanted to post the resolution to my particular my case. It turns out that my problem was that one of my css files was missing a closing brace and this was causing the file to not be compiled. It may be harder to notice this if you have an automated process that sets everything up (including the asset precompile) for your production environment.
After all else failed...
My solution was to change the layout file from
= stylesheet_link_tag "reset-min", 'application'
to
= stylesheet_link_tag 'application'
And it worked! (You can put the reset file inside the manifest.)
Just another way to fix this up on Heroku: Make sure your Rakefile is committed and pushed.
On heroku server (readonly filesystem),
If you want runtime compilation of css (its not recommended but you can do it), make sure you have done settings like below -
# inside config/application.rb
config.assets.enabled = true
config.assets.prefix = Rails.root.join('tmp/assets').to_s
# If you are using sass then keep gem outside of asset group
gem 'sass-rails', '3.1.4'
# inside config/environments/production.rb
config.assets.compile = true
if you think you followed everything good but still unlucky, just make sure you/capistrano run touch tmp/restart.txt or equivalent at the end. I was in the unlucky list but now :)
You probably have a syntax error in the css you are using.
Run this command
$ bundle exec rake assets:precompile RAILS_ENV=development --trace
It will give the exception, fixed that and you are all done.
Thanks

Resources