I recently attended Cloudstock at San Francisco. One of the hackathons I attended was about deploying a Ruby app that pushes to and retrieves records from DynamoDB, and uploading photos to S3. It involves several steps but thanks to Trevor Rowe (author of AWS SDK for Ruby) who helped me, I finally succeeded and created a implementation that works pretty nicely. He made a really good work so I will assume knowledge of ActiveRecord here, as it works in a pretty similar manner.
I included some information on how you could replicate this functionality on your Rails app in this Github repository. Either way I will explain better how to do it here.
To set this up, as we won’t use ActiveRecord, call:
rails new your_app_name --skip-active-record
In order to get the AWS Ruby functionality, add the ‘aws-sdk’ gem to your Gemfile and execute ‘bundle install’ to get everything set up.
See config/initializers/aws.rb . This gets called when Rails is initiated and it will log you in, provided you give your Amazon access_key_id and secret_access_key. The file should look like this:
Instead of getting functionality from ActiveRecord, we must inherit from AWS::Record, and attributes are hence defined in a different manner:
In order to write or retrieve information to S3, we use the following method, where images_cloudstock is the bucket in S3:
Be wary that you should implement some sort of mechanism to avoid making too many calls in order to avoid getting to your S3 quota quickly. In this example there is a boolean attribute that takes care not to call to the database if there is no image.
I included a file_field caption in the form so that the users can upload their photos to Amazon S3. This is only done whenever there is already an id in DynamoDB set for the record (if @user.id).
In order to show this photos I call the user model in index with (user.img) so that the image is retrieved from S3. Try to call this method only if you are sure that the record contains an image so you can avoid unnecessary calls to the database.
Default controller redirects to @user using the default Rails ids, which by convention are just integers. DynamoDB uses ids with hyphens, lowercase and uppercase alphanumeric characters, so you have to figure out a way to handle this in routes.rb. A regular expression works well.
4 thoughts on “Rails’ new seamless integration with Amazon’s DynamoDB and S3”
At last! Someone with real extpreise gives us the answer. Thanks!
I encourage you to use Fog instead, so that you can switch between uploading to a local FS or S3 in various environments (think testing). Even higher level, use CarrierWave.
Looks really cool. Thanks for sharing. I will have a look when hacking around on some new projects.
Any idea on the cost?