2018/06/09 記事を作成
はじめに
Ruby on Railsでよく使うformと言えば form_for
ですね。
このformは扱うデータが何かしらのModelに基づいていることを前提としていますが、S3等のクラウドストレージにデータを保存したい場合、Modelを作らないという選択肢もあるかと思います。
そこで form_for
ではなく form_tag
でformを作ろうと思ったのですが、筆者が調べた範囲では form_tag
でS3にデータをアップロードする的な記事はあんまりありませんでした。
そこで、今回筆者が実装した内容を以下に簡単にまとめようと思います。
この記事がどこかの誰かさんの参考になれば幸いです。
環境
OS: Ubuntu 16.04 LTS
ブラウザ: Chromium 66.0.3359.181(Official Build)Built on Ubuntu
S3とは
Amazon Simple Storage Service はインターネット用のストレージサービスです。また、ウェブスケールのコンピューティングを開発者が簡単に利用できるよう設計されています。
Amazon S3 のウェブサービスインターフェイスはシンプルで、いつでも、ウェブのどこからでも容量に関係なくデータを格納および取得できます。これにより、すべての開発者が、スケーラブルで信頼性が高く、かつ高速で安価なデータストレージインフラストラクチャを利用できるようになります。このインフラストラクチャは、Amazon が使用しているウェブサイトのグローバルネットワークと同じものです。このサービスの目的は、規模の拡大や縮小のメリットを最大限に活かし、開発者に提供することです。
(Amazon S3 とは何ですか? - Amazon Simple Storage Serviceより引用)
※本記事ではS3のバケットは既にあるものとして話を進めます。
実装
View
Viewはこんな感じ。
Slimで記述しています。
= form_tag({:action => "upload_image"}, :multipart => true) do
= file_field_tag :file, accept: 'image/jpg,image/jpeg,image/png'
= submit_tag "アップロード"
ここで重要なのは、multipartオプションを省略しないことです。
form_for
では省略しても大丈夫なのですが、 form_tag
の場合は省略してしまうとファイル名が文字列として渡るだけでファイル本体が取得できません。
ちなみに、 file_field_tag
に accept
オプションを追加することで画像のみが選択可能となるようにしています。
Controller
Controllerはこんな感じ。
def upload_image
source = params[:file]
notice = "画像を選択してください。"
if source
file_name = source.original_filename
s3 = Aws::S3::Resource.new(region: "ap-northeast-1")
obj = s3.bucket("my_bucket").object("images/#{file_name}")
obj.put({
body: source.read,
content_type: 'image/jpeg'
})
notice = "#{file_name}を保存しました。"
end
redirect_to images_path, :notice => notice
end
Aws::S3::Objectの put
メソッドを使用してS3に画像をアップロードしています。
また、 redirect_to
に notice
オプションを追加することで画像アップロードの成否を通知しています。
ちなみに、 params[:file]
で取得したオブジェクトは以下の感じでパラメータが取得できます。
- ファイル名を取得:
params[:file].original_filename
- コンテンツタイプの取得:
params[:file].content_type
- ファイルサイズの取得:
params[:file].size
- ファイル本体の取得:
params[:file].read
参考URL等
本記事の執筆にあたり参考にした順に並べています。
- 【Rails】form_for/form_tagの違い・使い分けをまとめた - Qiita
- Amazon S3 とは何ですか? - Amazon Simple Storage Service
- form_tag - リファレンス - - Railsドキュメント
- railsで画像などファイルをアップロードする方法 | Railsの小技 | DoRuby
- AWS SDK for Ruby を使用したオブジェクトのアップロード - Amazon Simple Storage Service
- redirect_to - リファレンス - - Railsドキュメント
- コントローラ(controller) - - Railsドキュメント