15
votes

This problem is driving me crazy... I think I've tried every conceivable combination of Sass file, ERB file, asset helper, image helper, etc. etc. Someone please give me new ideas!

Context:

Rails apps require use of asset helpers so that when the assets are precompiled, the source will be a fingerprinted asset file. I.e., if you just called img src="X.jpg", the site in production would look for X.jpg, but the file in public/assets has actually been fingerprinted as X-as;diofua;wemfiwaejfoiawefo.jpg. The only way to get to that fingerprinted file is to use an asset helper, e.g., image_url ('X.jpg').

Right now in my live site, I'm using an asset helper, but for whatever reason, it's not pointing at the fingerprinted asset. Note that the assets are found in development (but again, that's because there's no fingerprint added in development).

Code

Image titled "classic-map.png", located in app/assets/images/galleria

Image is called from a css.erb file required in the application.css file. In the css.erb file, I have the following code:

background-image: url(<%= asset_path 'galleria/classic-map.png' %>);

For reference, http://guides.rubyonrails.org/asset_pipeline.html Note that I'm choosing to write this as a css.erb file, hence the use of asset_path vs. asset-path. Also, I initially thought that the issue might have been in interpolation, but in the page source, the url is definitely working, it's just that it's pointing at url(galleria/classic-map.png) instead of url(galleria/classic-map-apsoidufalskjf;kasj.png)

A million kudos to whoever can help!

6
try once background-image: asset_url('galleria/classic-map.png');Rahul Singh
Nope didn't work, note i just edited my question, but this works in development, so the code appears right, it just appears that the asset helper is for whatever reason not pointing at the fingerprinted asset in productionjames
@james Did you ever find a fix for this?Noz
I found a hack for it @Noz, just added answer.james

6 Answers

4
votes

For what it's worth, this happened to be AGAIN, and this time I could not use the hack because I desperately needed the fingerprint. So somehow, magically, I ran a rake assets:clobber and heroku run rake assets:clobber to clean all assets, and then a straight up git push to force Heroku to do the precompilation for me. That did it, and everything works.

Now, when this happens, I clobber assets locally & in production and push, forcing Heroku to precompile remotely. Similar to @user2880239's answer. I have stopped precompiling locally and checking into git.

1
votes

I sat with a Sr Rails developer who still couldn't help me fix this. But the workaround we ended up using was that we just manually removed the asset fingerprint in the public folder (since the fingerpoint is what the asset helper is meant to point to).

I.e., the file galleria/classic-map-587854758918434124.png we just manually changed back to galleria/classic-map.png and it works fine.

Note that if you do this 'hack', the next time you precompile assets, Rails will create another fingerprinted asset, so you'll have duplication unless you want to keep deleting the additional fingerprinted asset each time. For me, I don't care about the duplication, I care about not thinking about this anymore.

1
votes

Did you check RAILS_ENV ?

bundle exec rake assets:precompile RAILS_ENV=production
0
votes

I had the same problem you did. This blog post helped me.

What I did was change a few things in my config/environments/production.rb file, namely...

config.serve_static_assets = true
config.action_dispatch.x_sendfile_header = ‘X-Accel-Redirect’
config.assets.compile = true

Note that you might not need to 'add' any of those properties since they may be pre-set to false or merely commented out.

Then I did the heroku dance:

rake assets:precompile
git add .
git commit -m "Fix static assets"
git push
git push heroku
0
votes

I'm having the same issue. I even tried the helper from the rails console from heroku, and the helper works fine there!!

$ heroku run rails console
Running `rails console` attached to terminal... up, run.8071
Loading production environment (Rails 4.1.7)

irb(main):001:0> puts helper.image_path("bg.jpg")
/assets/bg-00acfb7dbe138102509d82ac2313c24d.jpg

My final "solution" was to update config.assets.compile = true in config/environments/production.rb to fallback to the non fingerprinted image.

Hope this solution could help to someone. And if you had any real solution, please make me know!

0
votes

The answer to this for Heroku is in their Pipeline docs here.

By doing clobber you are basically cache-busting all your assets and forcing all clients to reload all static assets (even if they have not changed) every time you deploy your code. That is not advisable as it means every time you deploy ALL clients will experience slow loading times until all assets get cached again.

Your css file has a dependency to your image file, so you need to tell the assets pipeline about this by putting this at the top of your css:

//= depend_on_asset "galleria/classic-map.png"

This tells sprockets that if class-map.png gets a new fingerprint then the css must also get a new fingerprint. So it will only recompile the files (and dependencies that changed).

Also for others landing here, be aware that if you are using asset_path from ANYWHERE other than a view (eg in a model) you need to prepend the full context:

ActionController::Base.helpers.asset_path('your-image.png')

More info here.