user5289880
user5289880

Reputation:

Rendering images from root with image_tag

I have a folder in my root 'root/tmp/database/*.JPG' that I want to show in my view with a image_tag.

My current code for this is:

<% @images.each do |image| %>
  <%= image_tag image.file, class: "img-responsive"  %>
<% end %>

But because image_tag uses the asset pipeline it renders the images as:

'/images/tmp/database/xotter-1.jpg'

So my question is, is it possible that I use an image_tag and get the images rendered as: '/tmp/database/*.JPG'

Upvotes: 0

Views: 1025

Answers (2)

Richard Peck
Richard Peck

Reputation: 76774

Just to add to Max Williams' epic answer, if you populate your public folder with your images (instead of tmp), you'll be able to use the built-in asset_path helpers:

Computes the path to asset in public directory

asset_path "database/xotter-1.jpg" #-> /public/assets/database/xotter-1.jpg"

I appreciate this means you have to use the assets subdirectory, but there is a good reason for this...

--

Precompilation

Personally, I would put the images into the assets/images folder of your app.

The problem you'll have is that all of your images will remain "naked" in your public folder, which will both leave them open to hotlinking, but also prevent their proper use in the asset pipeline.

If you include the images in assets/images/...., you get to precompile the images when you push to production:

rake assets:precompile RAILS_ENV=production

Precompilation puts all the assets into the /public folder anyway... but more importantly, fingerprints them:

public/assets/images/database/xotter-1-[[fingerprint]].jpg

These images will still be available if you call image_tag databsae/xotter-1.jpg, but this time they'll be in their correct place.


All paths in Rails are taken from the public dir, so you can reference a link to the public dir directly, by using a relative path:

image_tag 'database/xotter-1.jpg

The difference is that if you put your images into assets/images, they are included in the asset pipeline, and thus will be accessible regardless of the environment you're running your app in.

Upvotes: 0

Max Williams
Max Williams

Reputation: 32933

All assets (images, css, js etc) served in your website need to come from somewhere inside the public folder. However, the public folder can contain symbolic links, aka shortcuts, to other folders.

So, for example, if you want to serve files from #{Rails.root}/tmp/database you can make a symbolic link like so:

#from your application folder
cd public
ln -s ../tmp/database database

You should now have the appearance of having the database folder inside your public folder, and can link to a file in it with the url

"/database/xotter-1.jpg"

which corresponds to a file at

#{Rails.root}/public/database/xotter-1.jpg

These instructions assume you are in a bash-style command line shell, eg in linux or mac os. If you are in windows you may need to set the shortcut up differently.

EDIT: an answer to your follow up question about displaying all images in a folder.

Let's say you have a folder #{Rails.root}/public/database and you want to find all jpg files in it: you can do that in a variety of ways. I like Dir[], used with File.join (which is a safe way to generate file paths which accounts for extra/missing slashes, which are otherwise easy to get wrong by mistake) eg

jpg_files = Dir[File.join("public/database", "*.jpg")]
=> ["public/database/foo.jpg", "public/database/bar.jpg"]

Note that these paths are all relative to where the command is run from, which in the case of a rails server or console is the rails application folder.

If you want to link to these, you will need the path relative to the public folder, which you can get by saying

filename.gsub("public","")
=> "/database/foo.jpg"

So, to tie this together, in your template:

<% Dir[File.join("public/database", "*.jpg")).each do |file| %>
  <%= image_tag file.gsub("public",""), class: "img-responsive"  %>
<% end %>

Upvotes: 2

Related Questions