In my latest application, I wanted to display full-width and full-height background images randomly from some web source.

I couldn't find any documentation about how to call a background image from a URL - and it's true that these things change over time and one day my application my hit a 404.  So I ended up putting 9 images that I liked (and own the rights to) in my assets/images folder, precompiling and pushing the application live.

The code for the randomization is like this:

<style>
.main_app {
font-size: 20px;
color: #fff;
background: url(<%= randomized_background_image %>) no-repeat center center fixed;
-webkit-background-size: cover;
-moz-background-size: cover;
-o-background-size: cover;
background-size: cover;
}
</style>

I put this in my layout file - application.html.erb.  Normally you wouldn't include CSS definitions like this directly in the html file - you put them in a css/scss/sass file.

But here we have a learning opportunity - we want to call a helper method that we defined called 'randomized_background_image' and we need to call it using ERB syntax so that it will be interpreted.  

I couldn't think of a better way to do it directly in the CSS file (and I found most of what I needed on Stack Overflow, so I left it alone).  I have a definition inside my primary CSS file in case this override ever chokes, but this helper method goes to Application Helper and is defined like so:

module ApplicationHelper
def randomized_background_image
images = [
("/assets/bg0.jpg"),
("/assets/bg1.jpg"),
("/assets/bg2.jpg"),
("/assets/bg3.jpg"),
("/assets/bg4.jpg"),
("/assets/bg5.jpg"),
("/assets/bg6.jpg"),
("/assets/bg7.jpg"),
("/assets/bg8.jpg")
]
images[rand(images.size)]
end
end

Pushing this out - you have a nice random image effect for the background of your site or app.  

Now there is a problem - which is the namesake of this post - there is no way that I could find to make those assets actually come from my defined asset site.

I use Amazon CloudFront in most of my projects, and I end up with a convention of:

http://cdn0.hostname.com
http://cdn1.hostname.com
http://cdn2.hostname.com

And so on through 9.  This allows us to skirt the limitation of a browser only opening a max of two simultaneous connections to a host.  When we want to serve lots of css, js, and image files concurrently (and quickly), we make sure to fake a bunch of random hostnames (which all go back to the same CloudFront URL of course) in order to get those things moving across the inter-tubes.

So back to our problem - normally from a view you can call:

<%= image_tag "bg" %> 

and rails will automagically figure things out for you - grab the image from either your public/assets directory or from your /assets directory if you have the fallback option enabled (disable it in production please).

In your CSS files, you might have used something like:

background-image: url('image.jpg');

In order to serve these assets through the asset pipeline.

But what if you are in my shoes?  You want to serve the assets through the asset pipeline from a Class?

The asset helper tags weren't really meant for that.

I tried solutions like the following:

ActionController::Base.helpers.image_path("/assets/bg0.jpg")

Or 

ActionController::Base.helpers.image_path("bg0.jpg")

And all manner of other trickery to get it working.  Alas - it was not to be.

The final solution I settled on?  Hardcode the damn links to the CDN files.

module ApplicationHelper
def randomized_background_image
images = [
("http://cdn0.hostname.com/assets/bg0.jpg"),
("http://cdn1.hostname.com/assets/bg1.jpg"),
("http://cdn2.hostname.com/assets/bg2.jpg"),
("http://cdn3.hostname.com/assets/bg3.jpg"),
("http://cdn4.hostname.com/assets/bg4.jpg"),
("http://cdn5.hostname.com/assets/bg5.jpg"),
("http://cdn6.hostname.com/assets/bg6.jpg"),
("http://cdn7.hostname.com/assets/bg7.jpg"),
("http://cdn8.hostname.com/assets/bg8.jpg")
]
images[rand(images.size)]
end
end