こんにちは、はんぺらです。
最近、仕事でもプライベートでも専らRailsを使うことが増えました。
RailsとはRubyOnRailsの事で、Ruby用のWebフレームワークになります。
RubyOnRailsもMVCのフレームワークになるんですが、こちらの記事でMVCフレームワークについて説明しているので、分からない方は読んでみてください。
さて、Web系の開発をしていると、よく要望として画像をアップロードしたいというものがあります。
そこで、RubyOnRailsでの画像のアップロードってどうしたらいいの?ってことで纏めてみました。結論だけ書くと、めちゃくちゃ簡単にアップロードできちゃいます。
Contents
まずは画像アップロードのおさらい
画像アップロードというと、下記が処理の流れになります。
まずは、フロントサイドの流れ
- ブラウザのフォームで画像を選択する
- ブラウザのフォームでアップロードボタンを押す
次に、サーバーサイドの流れ
- サーバー側でリクエストを受け取る
- リクエストで受け取った画像を保存先のディレクトリにコピーする
- 必要であれば画像のリサイズ等を行う。
- データベースで画像を管理していいれば、データベースに画像パスを追加
- 成功or失敗のレスポンスをブラウザに返す
という感じだと思います。
作ったことがある人は分かると思うんですが、正直画像アップロードを実装するだけでも、結構骨が折れる作業なんですよね。。。
RailsのGemを使えば簡単に画像のアップロードが実現できる
実はRailsだと画像アップロードはめちゃくちゃ簡単に実装できるんです。
方法としてはCarrierWaveというGemを使うことです。
https://github.com/carrierwaveuploader/carrierwave
このGemを使えば画像アップロードなんて秒で終わります。
すいません、勢いで「秒で」といいまいたが、5分くらいはかかります。。
とはいえ、めちゃくちゃ簡単に実装できたので、そのGemの使い方を紹介しますね。
CarrierWaveの使い方
CarrierWaveの使い方は下記4ステップだけです。
- CarrierWaveをGemに追加
- コマンド一発でアップロード用のクラスを作成
- アップロード用クラスの設定を更新
- アップロード処理を記述(わずか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等は劇的に開発スピードを上げてくれるので、サービス開発時には積極的に使っていきましょう。