rails でaws-sdk V2を使ってファイルをアップロードした時のメモ

ruby on railsで AWS S3にファイルをアップロートといえば、carrywaveとかfogとか使ってファイルをアップロードしますね。

僕も普段はその方法を使っているのですが、それらってそもそもmodelにuploaderを生成したりとかしているんですね。

今回は、jsからカジュアルに画像をアップロードする仕組みを作りたかったので、サーバーサイドからファイルをアップロードしました。

その時の対応をメモしておきます。

Gemfileに以下を記述

gem 'aws-sdk', '~> 2'

bundle installすると以下がインストールされます

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
<div>
  <input type="file" name="img"/>
</div>

<a>送信</a>
Javascript
  // 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でバイナリーを取得できます。

  def capture
   ImageLib.upload_capture_image(params[:file].tempfile)
    render :json => { :result => true }
  end

 

lib
# 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という名前で以下のように書くと読み込んでくれるようですが、私はうまく行きませんでした…

時間があるときに試してみたいと思います。

 

[default]
aws_access_key_id = 'アクセスキー'
aws_secret_access_key = 'シークレットキー'