ガラシのパルプンテ頼み

地方産限界エンジニアのグローバル独り言

【5分くらいでわかる】CarrierWaveでファイルをアップロードする方法 | Rails入門

CarrierWaveとは

CarrierWaveとは、Railsアプリケーションにファイルのアップロード機能を追加するためのgemです。 デフォルトの保存先はpublic/uploadsで、設定でS3などの外部ストレージへの保存も可能です。

GitHub github.com

CarrierWaveをローカルで使う

大まかな手順としては以下の通り。 それぞれ順を追って説明していきます。

  1. CarrierWaveをインストールする
  2. アップローダーを作成する
  3. アップロードファイル用のカラムを追加する
  4. アップローダーとカラムを紐づける
  5. アプリケーションから画像を登録する
  6. 画像を表示する

1. CarrierWaveをインストールする

$ gem install carrierwave

or Gemfileに以下を記述してbundle installを実行

gem 'carrierwave', '>= 3.0.0.beta', '< 4.0'

2. アップローダーを作成する

以下のコマンドの実行によりapp/uploaders/配下にAvatarUploaderクラスが作成されます

$ rails g uploader Avatar

アップローダーとは?

CarrierWave経由でアップロードするファイルの保存先、受け付ける拡張子の指定、 画像ならサイズや縦横比のフォーマットなどをあらかじめ指定するクラスです。 アップロード対象となるファイルの種別(画像、CSV、PDFなど)ごとに このアップローダーと後述のアップロード用カラムを用意する必要があります。 尚、アップローダークラスに storage :fileと記載することで、 public/uploads配下にファイルを保存することができます。

3. アップロードファイル用のカラムを追加する

次にアップロードしたファイルの情報を保存するカラムを追加します。

マイグレーションファイルを追加

$ rails g migration add_avatar_to_users avatar:string

マイグレーションを実行

$ rails db:migrate

なぜファイル名のみをDBに保持するのか?

上記で追加したavatarカラムには画像のバイナリではなく、ファイル名を保持します。 理由としては、単純にバイナリをそのまま保存するとサーバーの容量が圧迫されてしまうためです。 avatarカラムには、ファイルを特定するためのファイル名のみを保存して、表示時やダウンロード時に 「ファイルが格納されているパス + DBに保存されているファイル名」で表示を行います。

4. アップローダーとカラムを紐づける

アップロード機能を追加する対象モデルクラスで、3の手順で追加したavatarカラムと 2の手順で追加したAvatarUploaderクラスの紐付けを行います。

class User < ApplicationRecord
  mount_uploader :avatar, AvatarUploader
end

これでファイルアップロード時にAvatarUploaderクラスが利用できるようになりました。

5. アプリケーションから画像を登録する

ユーザー登録画面のviewに記述されている、formにfile_fieldを追加してファイル選択ボックスを作成する。

<%= form.label :avatar %>
<%= form.file_field :avatar %>

users_controllerではストロングパラメーターにavatarカラムを追加することを忘れないようにしましょう。

def user_params
  params.require(:user).permit(:name, :age, :avatar)
end

ファイル選択ボックスから画像を選択し、登録を実行すると、paramsのavatarキーに選択したファイルの情報が入ります。 @original_filenameがavatarカラムに保存され、バイナリは「public/uploads/モデル名/画像のカラム名/id」配下に保存されます。

6. 画像を表示する

アバター画像を表示させるには、まずは画像が保存されている場所(パス)を取得する必要があります。

UserモデルにてAvatarUploaderクラスとavatarカラムを紐づけを行っているので、以下のAvatarUploaderクラスのメソッドを使って 簡単にアップロードしたファイルの情報を取得することが出来ます。

ファイルのURLを取得

userインスタンス.avatar.url

カレントパス取得

userインスタンス.avatar.current_path

ファイル名を取得

userインスタンス.avatar.avatar_identifier

viewでimage_tagと上記メソッドを活用することでアップロードしたファイルの表示が行えます。

<% if @user.avatar? %>
  <p>
    <strong>Avatar:</strong>
    <%= image_tag @user.avatar.url %>
  </p>
<% end %>

表示の仕組み

public以下に配置したファイルは、Railsのデフォルトでブラウザに直接送信されるので、 アドレスバーにpublic以下のパス(url)を指定する事で、その画像をブラウザで表示する事が出来ます。