プログラミング

Railsで超簡単に画像をアップロードする方法

こんにちは、はんぺらです。

最近、仕事でもプライベートでも専らRailsを使うことが増えました。

RailsとはRubyOnRailsの事で、Ruby用のWebフレームワークになります。

RubyOnRailsもMVCのフレームワークになるんですが、こちらの記事でMVCフレームワークについて説明しているので、分からない方は読んでみてください。

さて、Web系の開発をしていると、よく要望として画像をアップロードしたいというものがあります。

そこで、RubyOnRailsでの画像のアップロードってどうしたらいいの?ってことで纏めてみました。結論だけ書くと、めちゃくちゃ簡単にアップロードできちゃいます。

まずは画像アップロードのおさらい

画像アップロードというと、下記が処理の流れになります。

まずは、フロントサイドの流れ

  1. ブラウザのフォームで画像を選択する
  2. ブラウザのフォームでアップロードボタンを押す

次に、サーバーサイドの流れ

  1. サーバー側でリクエストを受け取る
  2. リクエストで受け取った画像を保存先のディレクトリにコピーする
  3. 必要であれば画像のリサイズ等を行う。
  4. データベースで画像を管理していいれば、データベースに画像パスを追加
  5. 成功or失敗のレスポンスをブラウザに返す

という感じだと思います。
作ったことがある人は分かると思うんですが、正直画像アップロードを実装するだけでも、結構骨が折れる作業なんですよね。。。

RailsのGemを使えば簡単に画像のアップロードが実現できる

実はRailsだと画像アップロードはめちゃくちゃ簡単に実装できるんです。

方法としてはCarrierWaveというGemを使うことです。

https://github.com/carrierwaveuploader/carrierwave

このGemを使えば画像アップロードなんて秒で終わります。

すいません、勢いで「秒で」といいまいたが、5分くらいはかかります。。

とはいえ、めちゃくちゃ簡単に実装できたので、そのGemの使い方を紹介しますね。

CarrierWaveの使い方

CarrierWaveの使い方は下記4ステップだけです。

  1. CarrierWaveをGemに追加
  2. コマンド一発でアップロード用のクラスを作成
  3. アップロード用クラスの設定を更新
  4. アップロード処理を記述(わずか2行)

めちゃくちゃ簡単です。
順を追って説明していきます

CarrierWaveをGemに追加

まず、Rails用パッケージ管理であるGemにCarrierWaveを追加します。CarrierWaveをGemに追加する方法は2通りあります。

  • gem install コマンドを使用し最新版をインストール
  • Gemfile に直接CarrierWaveを追加

それぞれ説明しますね。

gem install コマンドを使用し最新版をインストール

下記コマンド一発です

$ gem install carrierwave

Gemfileに直接CarrierWaveを追加

下記をGemfileに追加

gem 'carrierwave', '>= 2.0.0.rc', '< 3.0'

下記コマンドを実行

$ bunlde install

簡単ですね。

コマンド一発でアップロード用のクラスを作成

次に、前ステップでインストールしたCarrierWaveのパッケージに含まれるClassを継承した、設定用ファイルを生成します。

下記コマンドで作成できます。

$ rails generate uploader TestImage

すると。下記のファイルが自動生成されます。

app/uploaders/test_image_uploader.rb

これを編集して、色々と設定を変えることができます。

アップロード用クラスの設定を更新

設定用ファイルで色々と細かく設定できるんですが、簡単に幾つか説明しますね。

画像の保存先を指定したい場合は下記を変更

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

デフォルト画像を設定したい場合は下記を変更

def default_url(*args)
    "/images/fallback/" + [version_name, "default.png"].compact.join('')
end

※ここに設定するファイルは、事前に自分でアップロードしておく必要があります。

アップロード後の画像名を変更したい場合は下記を変更

def filename
    "#{Time.now.strftime('%Y%m%d%H%M%S')}.#{file.extension.downcase}" if original_filename
end

僕はタイムスタンプで画像名を設定していました。

アップロード処理を記述(わずか2行)

下記2行でアップロードが完了します。

uploader = TestImageUploader.new
uploader.store!(params[:file])

params[:file]はHTMLのフォームから送られてきた画像用のリクエストパラメーターの値を渡して挙げれば良いです。

これだけで簡単に画像がアップロードできちゃいます。

その他、ActiveRecordと連携したりも出来ますし、保存先をS3等の外部ストレージに設定出来たりもでき、かゆい所に手が届きまくりです。

実際に自分が今作成中のサービスにもCarrierWaveを使わせていただいています。

まとめ

Railsで開発するときは、まずは自分がやりたいことを実現できるGemが無いか探してみましょう。

自分が実現したいと思う機能は、大体が先人のエンジニア達がGemを作ってくれていると思います。

ただ、メンテナンスされていないものもあるので注意が必要です。パッケージを選ぶ時はきちんとメンテナンスされているものを選びましょう。

自分で0から作る事も勉強をする時には大切ですが、サービスを作る時にはスピード感が大切になります。

RailsのGemやPHPのcomposer等は劇的に開発スピードを上げてくれるので、サービス開発時には積極的に使っていきましょう。