Writing to DynamoDB via Rails models

ActiveRecord is a core part of Rails, an ORM layer that sits on top of relational databases like Postgres or MySQL. However, it doesn’t natively support DynamoDB. Recently, we worked on a project to migrate part of a Rails app to Lambda functions. We began the migration by adding logic for writing to DynamoDB. Here’s how we did it.

Adding dynamoid and AWS credentials

To handle the DynamoDB connection we recommend dynamoid and the aws-sdk gems.

1
2
gem 'dynamoid'
gem 'aws-sdk'

After running bundle install we added a config file with the AWS secret key id and secret access key, under config/initializers/aws.rb.

1
2
3
4
Aws.config.update({
    region: 'eu-west-1',
    credentials: Aws::Credentials.new(ENV['secret_key_id'], ENV['secret_access_key'])
})

Adding a Rails Dynamo model

As with ActiveRecord, we need a model to act as the ORM layer (ODM in this case) between Rails and DynamoDB. We created a dynamo directory inside the models directory to separate the DynamoDB models from ActiveRecord models.

Here’s an example Dynamo model we created, for the User model. The file followed the naming convention of app/models/dynamo/user.rb. Let’s review the file contents, bit by bit.

1
2
3
4
5
6
7
8
9
10
11
module Dynamo
  class User
    include Dynamoid::Document

    table name: :user, key: :id, capacity_mode: :on_demand

    field :name, :string
    field :age, :integer
    field :admin, :boolean
  end
end

First we define a module, which is required because we’re nesting classes under the dynamo namespace. Next we have the User class definition. We then include Dynamoid::Document to mixin the dynamoid behaviour, which allows us to use the table and field methods.

We declare the table name, user, specifying the name of the key and specifying an on demand database. We then declare all the fields we want in our database. Remember, DynamoDB is noSQL so these fields can be changed at any time.

Executing the code to create a database

At this point, the code can be executed. The code can be run locally, as long as the AWS secret key id and secret access key are configured. We ran the Rails console and used the create method on Dynamo::User.

1
2
3
4
5
Dynamo::User.create(
  name: 'Bob',
  age: 20,
  admin: false
)

To confirm that everything worked, we can open AWS in the browser and check the DynamoDB UI. There’s a new table called dynamoid__development_user. Under ‘Explore items’ we can see the new record for ‘Bob’.