Using Rails 3.2.13 I get different asset paths for asset_path depending on whether or not i use .css.sass or just .css is this expected?
For example if I only have a app/assets/stylesheets/foo.css.sass in my stylesheet directory and nothing else, if I accidentally use an asset_path with the sass version I get a file that does not exist:
Loading production environment (Rails 3.2.13)
irb(main):001:0> helper.asset_path "foo.css.sass"
=> "/assets/foo-b148cf064a02aef053d2902b6a1fa5a9.css"
Using asset_path with just plain css produces the correct path.
irb(main):002:0> helper.asset_path "foo.css"
=> "/assets/foo-1b1fbb65d54bbc52b702c0f1d2efcc38.css"
Only foo-1b1fbb65d54bbc52b702c0f1d2efcc38.css is generated when i run rake assets:precompile. Does anyone know where the different hash value comes from?
Quick answer: I think that hash value is generated from the latest mtime of the compiled files.
Long answer: I dug around and can't confirm it, but I believe I've read that this hash-type string is generated from the latest mtime of all the file(s) you want to compile.
So my guess is foo.css is newer than foo.css.sass and so that mtime wins when precompiling.
If you want to dig further into it, I've tracked it to a digest_path method from within digest_for.
Related
I am referencing assets in my rails app directly, for ex. background-image: url('/assets/bg.png').
But I just realized this wouldn't work in production since digested assets are served (/assets/bg-dddasd434r4tfdfs...sada.png) in production.
Is my only choice to use helper methods (for ex, image-url) throughout the application or is there a more simpler solution to this?
You can try asset_path('app.js', :digest => false) or disable digest in the prodution env:
# config/environments/prodution.rb
config.assets.digest = false
Rails pipeline
In config/application.rb change the value of
config.assets.digest to false
This is an ancient question, but since I happened upon it with Google...
In Rails 5 there is the asset_path helper which even in the .scss files can return the proper path to a file.
My Rails app doesn't serve images at all.
image_url('picture.jpg')
# will result in url(http://localhost:3000/images/picture.jpg)
# but should be url(http://localhost:3000/assets/picture.jpg)
image_tag 'picture.jpg'
asset_url 'picture.jpg'
# will result in the same url / path as image_url()
Neither http://localhost:3000/images/picture.jpg nor http://localhost:3000/assets/picture.jpg exists, while http://localhost:3000/assets/images/picture.jpg does.
Here is a gist of my application.rb and development.rb: https://gist.github.com/maximski/1ccb75f6f89c02932239
I am in development environment and I don't want to precompile files manually. The app is pretty much much newly generated so the configuration is almost completely set on default.
This problem appear if images doesn't exists in app/assets/images directory. Check that app/assets/images/picture.jpg file is exists.
I've got somefile.js.coffee.erb file which is processed by Rails asset pipeline. My ERB code returns some string that cannot be parsed by Coffee which result in SyntaxError exception. I would like to peek into generated somefile.js.coffee file, or in general any intermediary file processed by asset pipeline.
I've tried to examine Sprockets with no luck:
environment = Sprockets::Environment.new
MyApplication::Application.config.assets.paths.each {|p| environment.append_path p}
rerb = environment['somefile.js.coffee.erb']
rerb.source #=> it's already preprocessed
Or to look into \tmp\cache\assets but there are also only preprocessed files, additionaly obscured by fingerprinted name.
Maybe there is a way to hook into asset-pipeline I have no idea how..
Why I need ERB? To generate client-side-model stubs with fields and validations matching Rails model using KnockoutJS (https://github.com/dnagir/knockout-rails extended -> https://github.com/KrzysztofMadejski/knockout-rails).
I am using Rails '~> 3.2.12', sprockets (2.2.2).
Edit: I've ended up injecting erb code in ### comments, to sneak-peak at generated code while coffeescript file is still compiling:
###
<%= somefun() %>
###
Altough I would suggest using #Semyon Perepelitsa answer as it produces coffee script file as it is seen by coffee compiler.
Just remove "coffee" from the file extension temporarily: somefile.js.erb. You will see its intermediate state at /assets/somefile.js as it won't be processed by CoffeeScript.
I wonder if you can put <% binding.pry %> just before the line and mess around till you get it right. Never tried during a compile and don't use coffeescript. In theory, it should work (or is worth a shot) so long as you put gem pry in your Gemfile and run bundle first.
I'm writing a Javascript-rich application in a Ruby on Rails 3.1 project and using Handlebars for my JS templating framework. I'm trying to figure out a way to dynamically append the MD5 digest of an asset (generated during asset precompilation on production) to my tags inside of my Handlebars template. I'm hoping that there's a hash with the asset path as the key and the MD5 digest as the value, but I haven't been able to find one.
An ideal solution would be passing the hash from Ruby into Javascript and defining a Handlebars helper that would automatically append the MD5 digest to the "src" attribute of the asset.
Has anybody attempted to do something similar? There must be a way to use Javascript templates in Rails and also reap the benefits of asset fingerprinting.
As someone mentioned in the comments, appending a hash to the asset paths is a default part of the asset pipeline.
In production, Rails inserts an MD5 fingerprint into each filename so that the file is cached by the web browser
You can read more about fingerprinting in the asset pipeline here. Rails uses Sprockets to compile assets. The fingerprinting comes as part of Sprockets process.
You can use Sprockets' find_asset method, passing in a logical path to your asset to get a Sprockets::BundledAsset instance. For example
[1] pry(main)> Rails.application.assets.find_asset('application.js')
=> #<Sprockets::BundledAsset:0x3fe368ab8070 pathname="/Users/deefour/Sites/MyApp/app/assets/javascripts/application.js", mtime=2013-02-03 15:33:57 -0500, digest="ab07585c8c7b5329878b1c51ed68831e">
You can call digest_path on this object to get it's MD5 sum appended to the asset.
[1] pry(main)> Rails.application.assets.find_asset('application.js').digest_path
=> "application-ab07585c8c7b5329878b1c51ed68831e.js"
With this knowledge you can easily create a helper to return the digest_path for any asset in your application, and call this helper from within your .js.erb files.
This is an old question, but it seems that nowadays you can use assets_manifest:
Rails.application.assets_manifest.assets["application.css"]
=> "application-46ae33e78e504ff295219f41d63c79719d062e48dc0c07bd9b6f7bcad72c6636.css"
More discussion here: https://github.com/rails/sprockets-rails/issues/311
I am working on a Rails 3.1 app. I have created an application.css.scss.erb file. The .erb is in the end because I want to load a variable from the config file as the color variable in the css:
$highlight1: #<%= COLOR.highlight1 %>;
$highlight2: #<%= COLOR.highlight2 %>;
Everything works fine, but the problem I am having is that whenever I change a value inside COLOR.highlight1, it doesn't reflect the change until I go in to my css file and change something (i usually add some spaces and save it). Thats when I see the change. Clearly rails is looking to see if the file was changed in order to update the change.
Is there any way that at least during development, this can be turned off and I can see the changes without having to also modify the css file?
Any critique/opinions on my technique are also welcome
The Sprockets depend_on directive is used to declare these kinds of dependencies. So at the top of your css.scss.erb file, with the other directives (require and friends), put something like:
//= depend_on "/path/to/colors.rb"
Then when the file /path/to/colors.rb changes, it will force the css to update too.
Unfortunately, I have never gotten this to work with a relative path to a file outside of one of the asset directories (javascripts/stylesheets/images) so there may be something in the way Sprockets resolves paths that prevents this, or else I'm missing something. That leaves you with the options of specifying an absolute path, which will almost certainly not work in across all your app environments, or putting the constants file into your asset directories (app/assets/stylesheets/colors.rb, for example).
For reference, here's the doc for the depend_on directive from the Sprockets (2.0.3) source, in sprockets/directive_processor.rb
# Allows you to state a dependency on a file without
# including it.
#
# This is used for caching purposes. Any changes made to
# the dependency file will invalidate the cache of the
# source file.
#
# This is useful if you are using ERB and File.read to pull
# in contents from another file.
#
# //= depend_on "foo.png"
#
If anyone does know a way to specify relative paths to other places like config/initializers or something, please let me know!
In addition to David Faber's answer. I needed to use relative paths too.
I wanted to generate a js file with the locale dictionary, which would update if the locale files were changed:
//= depend_on "../../../config/locales/en.yml"
//= depend_on "../../../config/locales/ja.yml"
var locales = <%= locales.to_json %>;
Turns out that currently (Rails 3.2.3) relative paths only work if the relative path is also in the assets path!
So the ugly solution is to add the path in config/application.rb:
config.assets.paths.unshift Rails.root.join("config", "locales").to_s
http://guides.rubyonrails.org/configuring.html
config.assets.compile is a boolean that can be used to turn on live Sprockets compilation in production.
might want to try that, I'm not sure if its getting compiled real time though, at least it should disable the caching.
maybe try:
config.assets.digest = true
in your development config file
I try this, it work
in application.rb
config.autoload_paths += %W(#{config.root}/lib/assets_variables)
config.assets.paths << File.join(Rails.root, 'lib', 'assets_variables')
in lib/assets_variables/color.rb
module Color
def self.default
'blue'
end
end
in app/assets/stylesheets/color.css.scss.erb
//= depend_on "color.rb"
$default_color: <%= Color::default %>;
.content {
color: $default_color;
}