Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
60
Help us understand the problem. What are the problem?

More than 5 years have passed since last update.

@sanryuu

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

概要

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ライセンスです。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
60
Help us understand the problem. What are the problem?