Upload an image to S3(AWS) on Rails app using Carrierwave and fog

First, we will go through how to use Carrierwave to upload an image file. Then, we’ll get into fog installation for S3.

  1. Install
gem ‘carrierwave’ # Gemfile
$bundle install

2. Create “Uploader” Class
After installing Carriewave, it’ll provide a generator called “uploader”. Use this to create a uploader class. Below is an example of creating a uploader class named “image”

$ rails g uploader image 

3. Set the uploader to a model class
As an example, we added a string-type column called “image” to a model class called “store” that has shop information.* The column name must match the uploader class name.(In this case “image”).

$ rails g migration addImageToStores image:string
$ rake db:migrate

*if you don’t have a model yet, do 
$ rails generate scaffold store name:string description:name

4. Hook up the uploader with the model.

class Store < ActiveRecord::Base
mount_uploader :image, ImageUploader
end

5. Edit View

We need to edit a form in order to upload an image file.

#app/views/stores/_form.html.erb
<div class=”field”>
<% if @store.image? %>
<div class=”thumbnail”>
<%= image_tag @store.image.url %>
</div>
<% end %><br>
<%= f.label :image %><br>
<%= f.file_field :image %>
<%= f.hidden_field :image_cache %>
</div>
<div class=”field”>
# if Image Exit
<% if @store.persisted? && @store.image? %>
<label>
<%= f.check_box :remove_image %>
画像を削除
</label>
<% end %>
</div>

image_cache (hidden) is used to retain an image file in case of a validation error for the image.

app/views/stores/show.html.erb

<p>
<strong>Image:</strong>
<% if @store.image? %>
<div class=”thumbnail”>
<%= image_tag @store.image.url %>
</div>
<% end %>
</p>

6. Edit Controller

Add “image” and “image_cache” to strong params

Now, let’s go to fog installation.

  1. Install
gem ‘fog’ # Gemfile
$ bundle install

2. Create a setting file for CarrierWave

Create config/initialize/carrierwave.rb. This is a configuration file to use AWS through fog from Carrierwave.

CarrierWave.configure do |config|
config.fog_credentials = {
provider: 'AWS',
aws_access_key_id: 'access_key',
aws_secret_access_key: 'secret_key',
region: 'ap-northeast-1'
}

case Rails.env
when 'production'
config.fog_directory = 'dummy'
config.asset_host = 'https://s3-ap-northeast-1.amazonaws.com/dummy'

when 'development'
config.fog_directory = 'dev.dummy'
config.asset_host = 'https://s3-ap-northeast-1.amazonaws.com/dev.dummy'

when 'test'
config.fog_directory = 'test.dummy'
config.asset_host = 'https://s3-ap-northeast-1.amazonaws.com/test.dummy'
end
end