Page caching trick on Heroku? - ruby-on-rails

I am moving a rails app to Heroku.
Heroku doesn't seem to support page caching.
So I generated cached pages on my development machine and checked them in to Heroku.
For example, /about_us generates public/about_us.html.
But when I call /about_us, public/about_us.html doesn't seem to be called.
Should my trick work?
Thanks.
Sam

In Rails 3, you'll be using the assets pipeline, so your assets--about_us.html--will be precompiled and put into a folder, WITHIN your public folder. Usually, this file will not be located at 'public/about_us.html'.
With your assets now precompiled, they'll be statically available and appended with an id, that will uniquely identify this asset until it is changed. With the unique signature, caching will occur on both Heroku's (last I checked) as well as within browsers.
Basically, the asset pipeline is doing this already for you.

Related

What happens when a Rails asset is requested with a digest that doesn't match the manifest?

I understand that, when pushing to production, Rails generates digests for assets, so that application.js will become application-2695540c610db8087315134277d8afe6.js. The digest/fingerprint is added to a manifest file so that Rails can keep track of them.
My question is: what happens if you request an asset with a different digest?
Please note that our app is set up so that Rails serves all assets, which then get cached by our CDN (which fronts all requests). From our observations, assets requested with the correct digest are served immediately, while others take time, which have us think that they might be compiled live.
The digests help with caching issues. If a user has already requested the previous digested asset then it will be cached on their machine. If for some reason the page tries to call that version of the asset then the user will be served the cached version. Otherwise if the asset is not cached on the users machine and the page tries to fetch it, the asset would be unreadable as it no longer exists.
The whole point of pre-compiled assets is that they are just files in the file system. If you are not deleting your old assets (ie, by creating a new directory for each deploy), they are still there, and the requests for them will succeed.
If you delete your old assets, then the server will respond with a 404 unless you have config.assets.compile turned on in production. Then you would be compiling assets on request, which is not how the asset pipeline is meant to work. That setting should be off in production, and you should be relying on statically compiled assets.
Typically your public folder, where your compiled assets reside, should be shared across all of your deploys, via symlink for example, so that pages requesting older assets are able to find them.

Rails 4 Heroku Assets not loading, though in heroku asset pipeline

I have a problem with certain assets on heroku. (local environment is working fine)
The assets are in the pipeline. If I execute in the heroku rails console:
helper.asset_path("typicons.woff")
helper.asset_path("backgrounds/1.jpg")
I get the following response:
/assets/typicons-c2430aad2b6a33948dc064cfaee8ad65ff9e3ca439834f3aaa84abec3d10dea8.woff
/assets/backgrounds/1-c2098ff7e7fbb89b2d18e9cd9089f712f2b837265d1d2e4182c36c23392760c6.jpg
So I assume that the assets are in the heroku asset pipeline. As well by opening the url directly with the digest in it, I receive the file.
However if I try to reference the files in css or javascript like this:
$('.top-content').backstretch("/assets/backgrounds/1.jpg");
The file does not load. As well opening /assets/backgrounds/1.jpg directly does not work. Referencing assets from .rb or .erb files works.
Please can someone tell me, what kind of config I have to change, so the URLs for assets work as well without the digest?
Thank you!
Assuming you are using a fairly standard asset pipeline setup, this passage from the Rails Guides should help:
If you add an erb extension to a JavaScript asset, making it something such as application.js.erb, you can then use the asset_path helper in your JavaScript code:
-- http://guides.rubyonrails.org/asset_pipeline.html (section 2.3.3)
In your example, add the erb extension to your JS file and then change the line to
$('.top-content').backstretch(<%= asset_path("backgrounds/1.jpg") %>);
The problem is that Rails 4 does not support non-digested assets at all.(For whatever reason)
Here is a more thorough explanation on the issue: Non Digested Asset Names in Rails 4
My personal workaround was to add a public asset folder to my app:
public/assets/static/
and upload the assets required there. Since it was only about fonts and background images, which do not change often, it does not seem to be a problem. In the link above there are several other solutions proposed.

Heroku does not display images and also is not accepting my authentication User/Pass for access..How can I access my images?

I have deployed my exhisting project to Heroku. My main pages display some images, which have not loaded on heroku ..... And my backend end authentication pages , accessible only by me, will not accept my user/pass.
images are stored in
app/assets/images
Several points for you
Images
Heroku runs an ephemeral file system, which essentially means your files are overwritten each time you push a new deploy.
This doesn't matter for asset based images, but if you're using the likes of Paperclip to store dynamically-uploaded images, you need to ensure you're able to persist the data (with the likes of S3)
--
Precompilation
In your case, the problem will likely be to do with the precompilation process:
In the production environment Sprockets uses the fingerprinting scheme
outlined above. By default Rails assumes assets have been precompiled
and will be served as static assets by your web server.
Precompilation of the assets is when the Rails application will serve assets from the /public directory, rather than the /assets dir. This is super important as it means if you're referencing assets using "static" CSS references, it simply won't work, especially on Heroku
The best solution for this is to use one of the Rails preprocessors (SCSS / SASS) & use one of the asset path helpers to reference the dynamic asset location:
#app/assets/stylesheets/application.css.scss
body {
background: asset_url("your_image.png");
}
--
Authentication
Your authentication is probably a problem with your database
A problem with Heroku is that as it uses a different database than your local system, you'll have to populate it with the data required to get it working.
It's a common issue to not be able to load the database correctly, missing out many different migrations. I would recommend the following:
$ heroku run rake db:migrate
After this, you need to ensure that you're able to create the relevant details in your application

Rails 4 Asset Pipeline: Asset missing fingerprint in asset_path from js

I am deploying a Rails 4.0 application which includes HTML partial templates as assets for our front-end javascript framework. Although these templates are part of the asset pipeline and are properly precompiled, when I call asset_path from embedded ruby in our js files, it returns the path to our templates without the fingerprint.
I am quite certain that this is purely a Asset Pipeline question, but to give you a complete sense of our tech stack: We use Rails 4.0, Ruby 2.1, AngularJS for our front-end MVC framework, and AssetSync to synchronize our assets between Rails and our CDN.
An example of where this occurs (in a file included in app/assets/application.js.erb:
$routeProvider
.when('/', {
templateUrl: "<%= asset_path 'home.html' %>",
controller: "HomeController"
});
This works great locally, but as soon as config.assets.digest = true in production, the call to asset_path does not properly factor in the fingerprint. The templates are in the app/assets directory within a new subdirectory templates. So in the above example, the home.html asset is at app/assets/templates/home.html. Our javascript has itself been precompiled at that point, so I'm thinking that it might be an issue of which order the assets are precompiled in.
I've noticed a few issues on the Rails Github (1, 2, 3) and a couple of SO posts about fingerprints not being set properly (1, 2), but can't find anything about them not being included at all...
Any help or ideas that you can provide would be much appreciated.
Edit 4/15: forgot to include that the extensions on my application javascript file DOES include .erb (app/assets/application.js.erb). Thanks Alex for catching that. I've updated it above.
Also, following instructions in this article on Heroku, I confirmed that running puts helper.asset_path("home.html") from within a Rails console running in production prints a properly fingerprinted URL for that asset.
This appears to be an issue with the AssetSync gem. I removed it, reconfigured the app so that Rails serves the assets, and the fingerprinting works fine.
If anyone else finds this question and is running into the same issue, I would recommend against using AssetSync. According to Heroku:
Many developers make use of Amazon’s S3 service for serving static assets that
have been uploaded previously, either manually or by some form of build process.
Whilst this works, this is not recommended as S3 was designed as a file storage
service and not for optimal delivery of files under load. Therefore, serving
static assets from S3 is not recommended.
Amazon CloudFront is the preferred method of serving assets through a CDN, and is very easy to configure with a Rails app that serves its own static assets, accomplishing the same goals as AssetSync.
I'm pretty new to this stuff, but to get the asset_path to work, don't you need a .erb on the end of that file?
Check out the bottom of this article for more info:
https://devcenter.heroku.com/articles/rails-4-asset-pipeline
If it works in development, that may not help. There is a helpful section on debugging at the bottom of the article though.
Update
Here's another article that could help:
https://medium.com/self-directed-learning/9ba1f595102a
Flipping on this configuration in Heroku made some of my asset pipeline problems go away:
heroku labs:enable user-env-compile -a yourapp
Hope this helps!
Alex

Heroku Rails 3 all.css / all.js dynamic generation?

I'm currently wrestling with a lot of all.js / all.css missing hits on a rails 2 upgraded to 3 app on Heroku. I'd prefer not to have a dozen or so stylesheet links per request, and also don't want to statically bundle -> s3 the files as part of the deploy.
This seems like a familiar problem, preparing some content specific to a url and sending it back to the browser.
Rather than using an external bundling app as part of a deploy script etc, has anyone considered having rails generate these files on-the-fly and use varnish to cache them (since it's cleared on redeploy, which is when the css/js files would change)?
My question is whether this has been done already & I just failed to google it, or if it sounds like a dumb idea, why?
Even better: Rails 3.1 asset pipeline does exactly this, and Heroku handles precompilation and caching for you.

Resources