user938363
user938363

Reputation: 10350

How to view/download file under a custom subdir in Rails 4?

After uploading a file, we would like to make the file available for view and download. The file could be in common format such as pdf, jpg or xls. After a user clicks the file name, the file is downloaded and opened by local app on user's PC. Here is what we did:

<%= link_to r.file_name, r.storage_subdir + '/' + r.file_name %>

r.storage_subdir returns storage/multi_item_orderx_order/15. storage is a subdir under root. r.file_name returns IMG_3002.jpg

When clicking the file name, there pops up an error:

No route matches [GET] "/upload/storage/multi_item_orderx_order/15/IMG_3002.jpg"

(Not sure how upload was put in front of storage). Used save link as to download and the file is only a partial in size and there shows nothing after clicking it. What is the right way to both view and download a file? Or at least to download a file.

Upvotes: 0

Views: 36

Answers (1)

axvm
axvm

Reputation: 2113

If you don't understand how to render uploaded file then you uploading it wrong. Here is a small tutorial for you.

How to implement file upload function in your rails application

First of all add this gems to your Gemfile and then execute bundle install in console.

gem "rmagick"
gem "carrierwave"

Let's imagine that you have model User and you need to give users ability to upload profile picture. When bundler install successfuly installed new gems we need to create Uploader via generator.

rails g uploader avatar

And let's configure it:

class AvatarUploader < CarrierWave::Uploader::Base
  include CarrierWave::RMagick

  storage :file

  def store_dir
    "uploads/#{mode.class.to_s.underscore}/#{mounted_as}/#{model.id}"
  end

  version :thumb do
    process resize_to_limit: [64, 64]
  end
end

Few words about this configuration: we said carrierwave to use RMagick gem, said which storage we would like to use and where data must be stored and implemented resize for thumbnails.

Now need to add column avatar to users table. Let's create migration:

rails g migration add_avatar_to_users avatar:string

And now lets mount our uploader in User model:

class User < ActiveRecord::Base
  mount_uploader :avatar, AvatarUploader
end

That's all! Carrierwave configured and ready to use in your application! Now you can create view like:

<%= form_for @user, html: {multipart: true} do |f| %>
  <%= f.file_field :avatar %>
  <%= f.submit %>
<% end %>

This form will give you ability to upload avatar. In controller you need to pass params[:user][:avatar] to model to create\update user's avatar.

And if you need to render image to view you can use something like this:

<%= image_tag @user.avatar_url(:thumb) %>

or

<%= image_tag @user.avatar.thumb.url %>

Don't forget to install imagemagick headers via system's package manager (apt-get \ yum \ pacman \ brew \ etc) because if you will not do it, bundler will fall.

If you got any questions, check out carrierwave github page and carrierwave documentation.

Upvotes: 1

Related Questions