How to upload and download file with AWS S3?

Programming Language

ruby 2.2.2p95 (2015-04-13 revision 50295) [x86_64-darwin14]

Framework

Rails 4.2.0

aws-sdk

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

set aws config

# config/initializers/aws.rb
AWS.config(
  access_key_id: ENV['ACCESS_KEY_ID'],
  secret_access_key: ENV['SECRET_ACCESS_KEY']
)

set autoload_paths for rails

# config/application.rb
config.autoload_paths << Rails.root.join('lib')                                                                                                                                 config.autoload_paths << Rails.root.join('lib/module')

make a s3 module

# lib/module/s3_module.rb
require 'aws-sdk'

module S3Module
  @s3 = AWS::S3.new
  @bucket = @s3.buckets[ENV['S3_BUCKET_NAME']]

  module_function

  def upload_file
    path = '/your/upload_file/path'
    Dir.glob(path + 'test.*').each do |file|
      basename = File.basename(file)
      send_result = @bucket.objects[basename]
      send_result.write(file: file)
    end
  end

  def download_file
    path = '/your/download_file/path'
    @bucket.objects.each do |object|
      file_path = path + object.key
      File.open(file_path, 'wb') do |file|
        object.read do |chunk|
          file.write(chunk)
        end
      end
      File.chmod(0777, file_path)
    end
  end

  def delete_file(filename)
    object = @bucket.objects[filename]
    object.delete
  end

  def exists_file(filename)
    object = @bucket.objects[filename]
    p object.exists?
  end
end

prepare test files

# under you upload_file path
test.txt
test.pdf

run rails runner

$ rails runner "S3Module.upload_file"
$ rails runner "S3Module.download_file"
$ rails runner "S3Module.delete_file('text.txt')"
$ rails runner "S3Module.exists_file('test.pdf')"

Rails 文件上传下载

上传

View

<%= form_for @salary, :url => { :action => "create" }, :html => { :class => "form-horizontal" }, :multipart => true do |f| %
  
"control-label" %>
"input-xxlarge" %>
</div> <% end %>

Controller

def create
    @salary = Salary.new(salary_params)
    @salary.file = upload_file(params[:salary][:pdf_file]) if params[:salary][:pdf_file] != nil
     ...
end

private

# Fiel Upload
def upload_file(file)
  name = file.original_filename
  # file extname : pdf
  # file size : blow 10 MB
  if !['.pdf'].include?(File.extname(name).downcase)
    flash[:warning] = "PDFのみアップロードできます。"
    return
  elsif file.size > 10.megabyte
  flash[:warning] = "10MBまでアップロードできます。"
    return
  else
    name = params[:salary][:user_id].to_s + '_' + params[:salary][:month].to_s + '_' + name
    File.open("public/uploads/#{name}", 'wb') { |f| f.write(file.read) }
  end
  return name
end

下载

View

<%= link_to @salary.file, users_download_path(:file => @salary.file) if @salary.file != nil %>

Controller

def download
  file_url = "public/uploads/#{params[:file]}"
  send_file file_url
end

Route

namespace :users do
  ...
  get "download", to: "salaries#download", as: "download"
end