- Install the gem
gem "paperclip", "~> 3.0"
# Create Database
class AddPhotoToDeals < ActiveRecord::Migration
def self.up
add_attachment :deals, :photo
end
def self.down
remove_attachment :deals, :photo
end
end
# Add to model
has_attached_file :photo, styles: {:medium => "300x300>", :thumb => "100x100>"},
default_url: "/images/missing.png"
# Remember to create an image at /images/missing.png
# Validation
validates_attachment :photo, presence: true,
content_type: {content_type: "image/jpg"},
size: {in: 0..1.megabytes}
# Individual validation
validates_attachment_presence :photo
validates_attachment_content_type :photo,
content_type: /^image\/(jpg|jpeg|pjpeg|png|x-png|gif)$/,
message: 'file type is not allowed (only jpeg/png/gif images)'
validates_attachment_size :photo,
in: 0..1.megabytes,
message: "file size cannot be larger than 1 MB"
# Add the following to your config/environments/production.rb and development.rb
config.paperclip_defaults = {
storage: :s3,
s3_protocol: 'http',
path: ":rails_root/public/system/production/:class/:attachment/:id_partition/:style/:filename",
s3_credentials: {
bucket: ENV['AWS_BUCKET'],
access_key_id: ENV['AWS_ACCESS_KEY_ID'],
secret_access_key: ENV['AWS_SECRET_ACCESS_KEY']
}
}
# Tip: Config needed to be set in production via command-line for Heroku
# heroku config:set AWS_BUCKET=stapi-us
# heroku config:set AWS_ACCESS_KEY_ID=XXXX
# heroku config:set AWS_SECRET_ACCESS_KEY=XXXX
# Alternative setup if you have errors with S3 endpoints
config.paperclip_defaults = {
storage: :s3,
s3_protocol: 'http',
path: "/production/:class/:attachment/:id_partition/:style/:filename",
s3_credentials: {
bucket: 'ABC',
access_key_id: '123123',
secret_access_key: '123123',
},
url: ":s3_domain_url"
}
= simple_form_for @product do |f|
= f.input :title
= f.input :photo
image_tag @product.photo.url
image_tag @product.photo.url(:thumb)
image_tag @product.photo.url(:medium)
describe "Create A Product" do
let(:product) { attributes_for(:product) }
it "should create a product" do
# Fill up create product form
fill_in 'Title', with: product[:title]
fill_in 'Description', with: product[:description]
attach_file "Photo", Rails.root.join('spec', 'fixtures', 'sample_photo.jpg') # Put your sample_photo.jpg at /spec/fixtures/sample_photo.jpg
click_button 'Create Product'
expect(page).to have_css "img.product_photo"
end
end
describe ProductsController do
# fixture_file_upload will search in /spec/fixture by default
let (:params) { attributes_for(:product).merge(photo: fixture_file_upload('sample_photo.jpg')) }
describe "#create" do
it "uploads the photo for the product" do
post :create, product: params
assigns(:product).photo.should_not be_nil
end
end
end
- Give a model Image with has_attached_file: :photo
FactoryGirl.define do
factory :image do
photo File.new(Rails.root + 'spec/fixtures/sample.jpg')
caption 'A nice caption'
end
end
# The above method is not good as it will generate real files in the app
# Just directly create fake data in the factory
FactoryGirl.define do
factory :image do
photo_file_name '123.jpg'
photo_content_type 'image/jpg'
photo_file_size 1024
photo_updated_at { DateTime.now }
caption 'A nice caption'
end
end