ruby on railsで AWS S3にファイルをアップロートといえば、carrywaveとかfogとか使ってファイルをアップロードしますね。
僕も普段はその方法を使っているのですが、それらってそもそもmodelにuploaderを生成したりとかしているんですね。
今回は、jsからカジュアルに画像をアップロードする仕組みを作りたかったので、サーバーサイドからファイルをアップロードしました。
その時の対応をメモしておきます。
Gemfileに以下を記述
1 |
gem 'aws-sdk', '~> 2' |
bundle installすると以下がインストールされます
1 2 3 |
Installing aws-sdk-core 2.3.8 Installing aws-sdk-resources 2.3.8 Installing aws-sdk 2.3.8 (was 1.56.0) |
クライアント
HTML
1 2 3 4 5 |
<div> <input type="file" name="img"/> </div> <a>送信</a> |
Javascript
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
// formにデータをセット var formData = new FormData(); if ($("input[name='img']").val() !== '') { formData.append( "file", $("input[name='img']").prop("files")[0] ); } $.ajax({ url: "/capture", method: "PATCH", dataType: "json", data: formData, processData: false, contentType: false, }).done(function( res ) { if(res.result == true) { // アップロード成功 } else { // アップロード失敗 } }).fail(function( xhr, status, error ) { // アップロード失敗 }); |
サーバーサイド
Ruby on Railsですが、Controllerでリクエストを受け付けてから自作のライブラリーでawsにアップロードしています。処理が終わったらjsonで結果を返しています。この記事ではバリデーションやエラーハンドリングなどは無視しています。libで使用している’AWS_CONFIG’は、こちらで用意したconstantsです。設定情報は皆さんよしなにして下さい。
※ githubなどで公開されないようにして下さい。
Controller
ajaxで送られたデータは”ActionDispatch::Http::UploadedFile”オブジェクトとして扱われます。temfileでバイナリーを取得できます。
1 2 3 4 |
def capture ImageLib.upload_capture_image(params[:file].tempfile) render :json => { :result => true } end |
lib
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
# encoding: utf-8 class ImageLib # 画像だけアップロードする def self.upload_capture_image(file) # Awsのconfigを設定 Aws.config[:credentials] = Aws::Credentials.new(AWS_CONFIG[:access_key_id], AWS_CONFIG[:secret_access_key]) Aws.config[:region] = 'ap-northeast-1' # aws clientを生成 s3 = Aws::S3::Client.new # アップロード s3.put_object( bucket: AWS_CONFIG[:bucket_name], body: file, key: "bucket内のアップロードするディレクトリ/ファイル名" ) end end |
これでアップロードができます。あくまで記事に載せたのは簡略版なので、バリデーションやエラーハンドリングは自分で実装してね。
詳しくは公式の情報を閲覧下さい。
https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/dev/UploadObjSingleOpRuby.html
※ AWSの設定は.awsという名前で以下のように書くと読み込んでくれるようですが、私はうまく行きませんでした…
時間があるときに試してみたいと思います。
1 2 3 |
[default] aws_access_key_id = 'アクセスキー' aws_secret_access_key = 'シークレットキー' |
コメントを残す