Upload Files to Google Cloud Storage with CarrierWave

Snippet Ruby on Rails

Last updated Feb 16, 2016

Uploading files to a Content Delivery Network (CDN) is a feature that is best implemented during the early stages of development. The following lesson will show you have to upload images to Google Cloud Storage using Rails and CarrierWave.

TIP: If you’re deploying to Heroku, you can’t save images to the public directory on its read-only filesystem. Therefore, it’s essentially required to use a CDN, such as Google, S3, RackSpace, or similar. To get started, add the following gems to your Gemfile.

Gemfile

gem 'carrierwave'
gem 'mini_magick'
gem 'fog'

Lesson Resources

Lesson Checkpoints

1. Setup a Google Developer Account

Start a New Project

Head over to the Google Developers Console and create a New Project.

Create a Storage Bucket

Create a Google Storage Bucket. At this point, you will need to enter billing information to use Cloud Storage. At the time of writing this lesson Google is offering a 3 month $300 credit free trial.

Get Interoperable Storage Access Keys

To push files to your bucket, you will need to access the Interoperable Storage Access Keys. Click CloudStorage >> Project Dashboard. Then you should see a link for Interoperable Access. You will need the API keys form this page. 

2. Protect API Credentials with secrets.yml

Before going any further, we need a secure place to store the Storage Access Keys. Rails 4.1 introduced a new secrets.yml file to manage sensitive keys. This gives us the Rails.application.secrets.your_api_key method to access the API values throughout the application.  If you're on an older version of Rails, install the figaro gem to get the same type of functionality.

config/secrets.yml

development:
google_storage_access_key_id: "YOUR-ID"
google_storage_secret_access_key: "YOUR-SECRET"

3. Implement CarrierWave for File Uploads

Let’s add an image model to our rails app to handle file uploads with CarrierWave. The file attribute will be used to hold the path to the uploaded file.

console

$ rails g scaffold Image name:string file:string
$ rails g uploader Image

models/image.rb

class Image < ActiveRecord::Base
  mount_uploader :file, ImageUploader
end

In the uploader file, comment out or remove the storage :file and replace it with storage :fog

uploaders/image_uploader.rb

class ImageUploader < CarrierWave::Uploader::Base
  storage :fog
  # ... other code omitted 
end

4. Create an Initializer File

The next step is to create an initializer file that will pass the API credentials and bucket name to Google.

config/initializers/carrierwave.rb

CarrierWave.configure do |config|
config.fog_credentials = {

    :provider                         => 'Google',
    :google_storage_access_key_id     => Rails.application.secrets.google_storage_access_key_id,
    :google_storage_secret_access_key => Rails.application.secrets.google_storage_secret_access_key

    }

    config.fog_directory = 'your-bucket-name'
end

5. Upload Files from the View

Now any uploads submitted through your app will be sent directly to your Google Storage Bucket.

views/images/new.html.erb

<%= form_for(@image) do |f| %>
  <div class="field">
      <%= f.text_field :name %>
     </div>
     <div class="field">
      <%= f.file_field :file %>
     </div>
     <div class="actions">
      <%= f.submit %>
     </div>
    <% end %>

If you inspect the images, the img src should point to https://commondatastorage.googleapis.com/, rather than your app’s public folder.

Comments