I have a rails 3.1 app and I am adding carrierwave to store images. But I want to store those images outside the public folde,r because they should only be accessible when users are loaded in the app. So I changed the store_dir in carrerwave with the initializer file:
CarrierWave.configure do |config|
config.root = Rails.root
end
And my carrierwave uploader goes like this:
class ImageUploader < CarrierWave::Uploader::Base
...
def store_dir
"imagenes_expedientes/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
end
Images are stored correctly and if I use the public folder everything works fine. However when trying to move things to the private folder, images are not displayed and when I try to open them in a new window I get the following error:
Routing Error
No route matches [GET] "/imagenes_expedientes/volunteer/avatar/15/avatar.jpg"
I was trying to deliver the files using send_file through the controller, but instead of loading the page I only get the image downloaded.
def show
send_file "#{Rails.root}/imagenes_expedientes/avatar.jpg", :type=>"application/jpg", :x_sendfile=>true
end
Finally Images are displayed like this in the views:
<%= image_tag(@volunteer.avatar_url, :alt => "Avatar", :class => "avatar round") if @volunteer.avatar? %>
This may probably be solved rather easy, but since I am somehow new to Rails, I donĀ“t know what to do it. Should I set a route? Or is there anyway to display the images using the send_file method?
Thanks!
ANSWER
I managed to display images using x-sendfile and putting :disposition => 'inline' as suggested by clyfe. I made a new action in my controller:
def image
@volunteer = Volunteer.find(params[:id])
send_file "#{Rails.root}/imagenes_expedientes/#{@volunteer.avatar_url}",:disposition => 'inline', :type=>"application/jpg", :x_sendfile=>true
end
Added to the routes:
resources :volunteers do
member do
get 'image'
end
end
And displayed in the views:
<%= image_tag(image_volunteer_path(@volunteer), :alt => "Avatar", :class => "avatar round") if @volunteer.avatar? %>
Hope it helps others!
Best Answer
:disposition => 'inline'
will make your images display in the browser instead of popping up the download dialog.Depending on the images sizes and the number of users you might want to move this action to a metal app, or a separate so as to not block the server.