Edited at

Railsでアップローダを作って覚えるCarrierwaveのチュートリアル

More than 3 years have passed since last update.


概要

Carrierwaveのサンプルコードは、画像の処理とscaffoldが多いので自力でアップローダを作ってみるチュートリアルを作りました。

最低限Railsが動く状態からスタートすることを想定しています。


実装手順


ライブラリを準備する

Gemfileに以下の行を追加

gem 'carrierwave'

以下のコマンドでインストール

bundle install


モデルを準備する

carrierwaveのuploaderを生成する

rails generate uploader UploadFile

uploaderの細かい設定を行いたい場合には、 /app/uploaders/upload_file_uploader.rb を変更する。

コマンドでファイルを扱うためのモデルを作成

rails generate model UploadFile name:string file:string

以下のコマンドでDBを生成

rake db:migrate

生成したモデルに、mount_uploaderを追加する。

このときに追加するのは、rails generate uploaderで生成したUploadFileなので、

末尾にUploaderを追加して、UploadFileUploaderになる。


/app/models/upload_file.rb

class UploadFile < ActiveRecord::Base

+ mount_uploader :file, UploadFileUploader
end

これでモデルに関する部分は完成。


UIからアップロードできるようにする

アップロードするためのWebの処理を作成する

後から使うdownloadやindexも同時に生成しておく

rails generate controller uploader index form upload download

フォームを用意する


/app/views/uploader/form.html.erb

    <% @upload = UploadFile.new %>

<%= form_for @upload, :url => {:action => :upload} do |f| %>
<%= f.label :name, "name" %>
<%= f.text_field :name %>
<%= f.label :file %>
<%= f.file_field :file %>
<%= f.submit "Upload" %>
<% end %>

コントローラの生成時に自動的に生成されたroutes.rbがPOSTを受け取るように手直しする。


/config/routes.rb

+  post 'uploader/upload'

- get 'uploader/upload'

ファイルを保存してindexにリダイレクトする処理をコントローラに追加


/app/controllers/uploader_controller.rb

  def upload

@upload_file = UploadFile.new( params.require(:upload_file).permit(:name, :file) )
@upload_file.save
redirect_to action: 'index'
end


アップロードしたファイル一覧を見れるようにする

アップロードされたファイルの一覧を確認する。


/app/views/uploader/index.html.erb

    <%= link_to 'アップロードはこちら', action: "form" %>

<ul>
<% UploadFile.all.reverse_order.each do |upload| %>
<li><%= link_to upload.name, action: "download", id: upload.id %>
<% end %>
</ul>


ダウンロードできるようにする

ダウンロードにはRailsのdownload用のメソッドsend_fileを使う

uploderのcurrent_pathを指定してダウンロードできるようにしている。


/app/controllers/uploader_controller.rb

  def download

+ @upload_file = UploadFile.find(params[:id].to_i)
+ filepath = @upload_file.file.current_path
+ stat = File::stat(filepath)
+ send_file(filepath, :filename => @upload_file.file.url.gsub(/.*\//,''), :length => stat.size)
end

データを1つ以上アップロードした後にRails Consoleを使って見てみると、

モデルの中がどんなオブジェクトになっているのか確認できる。


rails console

> UploadFile

#=> UploadFile(id: integer, name: string, file: string, created_at: datetime, updated_at: datetime)

> UploadFile.first.file.class
#=> UploadFileUploader

> ploadFile.first.file
#=> #<UploadFileUploader:0x007fb75c6fc3e8 @model=#<UploadFile id: 1, name: "hoge", file: "hoge.pdf", created_at: "2015-04-12 17:40:45", updated_at: "2015-04-12 17:40:45">, @mounted_as=:file, @storage=#<CarrierWave::Storage::File:0x007fb75c6fc118 @uploader=#<UploadFileUploader:0x007fb75c6fc3e8 ...>>, @file=#<CarrierWave::SanitizedFile:0x007fb75ba16ca0 @file="/Users/user_name/app_name/public/uploads/upload_file/file/1/hoge.pdf", @original_filename=nil, @content_type=nil>, @versions={}>



参考文献


ライセンス

こちらのコードはMITライセンスです。