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.