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!
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!
The first gem is for CarrierWave, and the second gem called mini_magick helps with the resizing of images in your Rails application. With that done, run bundle install. Generate a scaffold resource to add CarrierWave’s functionality. Run the following command from your terminal:
The first one is the worst idea as it sends the entire image as plain text. While the later one multipart is preferable way to send file as it send the image data byte by byte. In Rails, we have few prominent gem Carrierwave , Paperclip , Dragonfly, etc, to implement this concept.
By default, CarrierWave copies an uploaded file twice, first copying the file into the cache, then copying the file into the store. For large files, this can be prohibitively time consuming.
We go with Carrier w ave as it simple and flexible to configure and include in Rails. It has a lot more flexibility and it doesn’t clutter your models with configuration.You can define uploader classes instead. It allows you to easily reuse, extend etc your upload configuration.
:disposition => 'inline'
will make your images display in the browser instead of popping up the download dialog.
def show
send_file "#{Rails.root}/imagenes_expedientes/avatar.jpg", :disposition => 'inline', :type=>"application/jpg", :x_sendfile=>true
end
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With