Skip to content

Instantly share code, notes, and snippets.

@roalcantara
Last active February 25, 2018 16:06
Show Gist options
  • Save roalcantara/11260231 to your computer and use it in GitHub Desktop.
Save roalcantara/11260231 to your computer and use it in GitHub Desktop.
Rails 4 + Paperclip + Amazon S3
<!-- /views/admin/products/_form.html.erb -->
<%= form_for @product, html: {multipart: true, role: 'form'} do |f| %>
<div class="form-group">
<%= f.label :photo %>
<%= f.file_field :photo %>
</div>
<%= f.submit %>
<% end %>
#/config/initializers/aws.rb
require 'aws-sdk'
# Rails.configuration.aws is used by AWS, Paperclip, and S3DirectUpload
Rails.configuration.aws = YAML.load(ERB.new(File.read("#{Rails.root}/config/aws.yml")).result)[Rails.env].symbolize_keys!
AWS.config(logger: Rails.logger)
AWS.config(Rails.configuration.aws)
#/config/initializers/aws.yml
defaults: &defaults
#https://console.aws.amazon.com/iam/home?#users -> Security Credentials (S3_user_policy.json)
access_key_id: 'dadfssdsa'
secret_access_key: 'saddaadsa'
#necessary if the bucket is outside US: http://docs.aws.amazon.com/general/latest/gr/rande.html
region: 'ap-southeast-2'
development:
<<: *defaults
bucket: 'bucket-development'
production:
<<: *defaults
bucket: 'bucket-production'
#https://github.com/thoughtbot/paperclip
#http://rubydoc.info/gems/paperclip/Paperclip/Storage/S3
gem 'paperclip', github: 'thoughtbot/paperclip'
# S3 API
gem 'aws-sdk'
#/config/initializers/paperclip.rb
Paperclip::Attachment.default_options.merge!(
url: ':s3_domain_url', #domain-style, e.g: bucket-development.s3-eu-west-1.amazonaws.com
path: '/:class/:attachment/:id/:style/:filename',
storage: :s3,
s3_credentials: Rails.configuration.aws
)
#/models/product.rb
class Product < ActiveRecord::Base
has_attached_file :photo,
styles: {large:'400x450>', medium:'300x300>', thumb:'100x100>'},
default_url: '/images/:style/missing.png'
validates_attachment :photo,
content_type: {content_type:['image/jpg', 'image/jpeg', 'image/gif', 'image/png']},
size: {in: 0..500.kilobytes}
end
#/controllers/products_controller.rb
class ProductsController < ApplicationController
before_action :set_products, only: [:show, :edit, :update, :destroy]
# GET /products
# GET /products.json
def index
respond_to do |format|
format.html { @products = Product.all }
format.json { @products = Product.order(:name) }
end
end
# GET /products
# GET /products.json
def list
@products = Product.all
end
# GET /products/1
# GET /products/1.json
def show
end
# GET /products/new
def new
@product = Product.new
end
# GET /products/1/edit
def edit
end
# POST /products
# POST /products.json
def create
@product = Product.new(product_params)
respond_to do |format|
if @product.save
format.html { redirect_to [:admin, @product], notice: 'Product was successfully created.' }
format.json { render action: 'show', status: :created, location: @product }
else
format.html { render action: 'new' }
format.json { render json: @product.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /products/1
# PATCH/PUT /products/1.json
def update
respond_to do |format|
if @product.update(product_params)
format.html { redirect_to [:admin, @product], notice: 'Product was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: 'edit' }
format.json { render json: @product.errors, status: :unprocessable_entity }
end
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_products
@product = Product.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def product_params
params.require(:product).permit :photo
end
end
<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
<AllowedOrigin>*</AllowedOrigin>
<AllowedMethod>GET</AllowedMethod>
<AllowedMethod>POST</AllowedMethod>
<AllowedMethod>PUT</AllowedMethod>
<MaxAgeSeconds>3000</MaxAgeSeconds>
<AllowedHeader>*</AllowedHeader>
</CORSRule>
</CORSConfiguration>
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowPublicRead",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": ["arn:aws:s3:::bucket-development/*"]
}
]
}
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Action": ["s3:ListBucket" ],
"Resource": ["arn:aws:s3:::bucket-development", "arn:aws:s3:::bucket-prod"]
},
{
"Effect": "Allow",
"Action": ["s3:DeleteObject", "s3:GetObject", "s3:PutObject", "s3:PutObjectAcl"],
"Resource": [
"arn:aws:s3:::bucket-development/*", "arn:aws:s3:::bucket-prod/*"
]
}
]
}
<!-- /views/admin/products/show.html.erb -->
<%= image_tag @product.photo.url(:thumb) %>
<!-- http://bucket-development.s3-eu-west-1.amazonaws.com/products/photos/1/thumb/shop2.jpg?139835258 -->
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment