Problem
Sometimes you’ll need to install very specific verion of bundler and run bundle install for example on your Ruby on Rails project.
Super easy way to do that with command line:
Let’s start
Let’s add two gems into our Gemfile
and set our AWS credentials:
gem 'dynamoid'
gem 'aws-sdk'
We can use aws.rb
in initializers
directory:
Aws.config.update({
region: 'ca-central-1',
credentials: Aws::Credentials.new('XXX', 'XXX'),
})
Let’s create model which is describes document with one validation:
class OrderLog
include Dynamoid::Document
field :order_id, :integer
field :comment, :string
field :created, :datetime
validates_presence_of :comment
end
We’re using interactor
gem here, so one more line in AddLog
interactor:
class AddLog
include Interactor
def call
# Call new model's create method
OrderLog.new(comment: "ORDER_WITH_PRICE_#{context[:total_price]}").save!
Rails.logger.info("ADDING ORDER WITH TOTAL PRICE: #{context[:total_price]}")
end
end
Testing
As a first step, let’s try to create object from console:
irb(main):005:0> OrderLog.new(comment: "Hello").save!
[Aws::DynamoDB::Client 200 0.126174 0 retries] list_tables(exclusive_start_table_name:nil)
(147.02 ms) LIST TABLES
(147.09 ms) CACHE TABLES
Creating dynamoid__development_orderlogs table. This could take a while.
[Aws::DynamoDB::Client 200 0.061382 0 retries] create_table(table_name:"dynamoid__development_orderlogs",key_schema:[{attribute_name:"id",key_type:"HASH"}],attribute_definitions:[{attribute_name:"id",attribute_type:"S"}],billing_mode:"PROVISIONED",provisioned_throughput:{read_capacity_units:100,write_capacity_units:20})
[Aws::DynamoDB::Client 200 0.034059 0 retries] describe_table(table_name:"dynamoid__development_orderlogs")
Checked table status for dynamoid__development_orderlogs (check {:again=>true, :status=>"CREATING", :counter=>0})
[Aws::DynamoDB::Client 200 0.041893 0 retries] describe_table(table_name:"dynamoid__development_orderlogs")
Checked table status for dynamoid__development_orderlogs (check {:again=>true, :status=>"CREATING", :counter=>1})
[Aws::DynamoDB::Client 200 0.032142 0 retries] describe_table(table_name:"dynamoid__development_orderlogs")
Checked table status for dynamoid__development_orderlogs (check {:again=>false, :status=>"ACTIVE", :counter=>2})
(6181.32 ms) CREATE TABLE
[Aws::DynamoDB::Client 200 0.028371 0 retries] put_item(table_name:"dynamoid__development_orderlogs",item:{"comment"=>{s:"Hello"},"created_at"=>{n:"1646972339.942993"},"updated_at"=>{n:"1646972339.943931"},"id"=>{s:"c898ac71-dd82-49c4-adb5-ba68965161cc"}},expected:{"id"=>{exists:false}})
(29.33 ms) PUT ITEM - ["dynamoid__development_orderlogs", {:comment=>"Hello", :created_at=>0.1646972339942993e10, :updated_at=>0.1646972339943931e10, :id=>"c898ac71-dd82-49c4-adb5-ba68965161cc"}, {}]
=> #<OrderLog:0x0000000119a259f8 @new_record=false, @attributes={:comment=>"Hello", :created_at=>Fri, 11 Mar 2022 04:18:59 +0000, :updated_at=>Fri, 11 Mar 2022 04:18:59 +0000, :id=>"c898ac71-dd82-49c4-adb5-ba68965161cc"}, @associations={}, @attributes_before_type_cast={:comment=>"Hello", :created_at=>Fri, 11 Mar 2022 04:18:59 UTC +00:00, :updated_at=>Fri, 11 Mar 2022 04:18:59 UTC +00:00, :id=>"c898ac71-dd82-49c4-adb5-ba68965161cc"}, @validation_context=nil, @errors=#<ActiveModel::Errors:0x0000000119a24f58 @base=#<OrderLog:0x0000000119a259f8 ...>, @messages={}, @details={}>, @changed_attributes={}, @_touch_record=nil, @previously_changed={"comment"=>[nil, "Hello"], "created_at"=>[nil, Fri, 11 Mar 2022 04:18:59 +0000], "updated_at"=>[nil, Fri, 11 Mar 2022 04:18:59 +0000], "id"=>[nil, "c898ac71-dd82-49c4-adb5-ba68965161cc"]}>
Cool!
Application testing
Now, let’s try to create an Order
, and check console:
Started POST "/orders" for ::1 at 2022-03-10 23:25:38 -0500
Processing by OrdersController#create as HTML
Parameters: {"authenticity_token"=>"Ksy6rbisUpKK3uEjwEyv3piwDR4YB18zcUAe84bQqSUjvOUsDXSLLpBBkPkLAGNNhTeBau6G/GefPpOGX+VDMA==", "order"=>{"title"=>"DYNAMO", "total_price"=>"999"}, "commit"=>"Create Order"}
(0.2ms) BEGIN
↳ app/interactors/order_init.rb:7:in `call'
Order Create (0.7ms) INSERT INTO "orders" ("title", "total_price", "created_at", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "id" [["title", "DYNAMO"], ["total_price", "999.0"], ["created_at", "2022-03-11 04:25:38.684555"], ["updated_at", "2022-03-11 04:25:38.684555"]]
↳ app/interactors/order_init.rb:7:in `call'
(2.1ms) COMMIT
↳ app/interactors/order_init.rb:7:in `call'
[Aws::DynamoDB::Client 200 0.338816 0 retries] list_tables(exclusive_start_table_name:nil)
(357.38 ms) LIST TABLES
(357.51 ms) CACHE TABLES
[Aws::DynamoDB::Client 200 0.063373 0 retries] put_item(table_name:"dynamoid__development_orderlogs",item:{"comment"=>{s:"ORDER_WITH_PRICE_999"},"created_at"=>{n:"1646972739.051647"},"updated_at"=>{n:"1646972739.052237"},"id"=>{s:"5504f1ea-d04f-4226-9488-c62377a0bebe"}},expected:{"id"=>{exists:false}})
(65.85 ms) PUT ITEM - ["dynamoid__development_orderlogs", {:comment=>"ORDER_WITH_PRICE_999", :created_at=>0.1646972739051647e10, :updated_at=>0.1646972739052237e10, :id=>"5504f1ea-d04f-4226-9488-c62377a0bebe"}, {}]
ADDING ORDER WITH TOTAL PRICE: 999
Completed 200 OK in 441ms (Views: 0.8ms | ActiveRecord: 3.0ms | Allocations: 39941)
Works!
5 mins with AWS console
Let’s go to the AWS console and look at DynamoDB:
Here you can see generated table name and status:
Table structure:
Our test file was created!
Let’s explore our table entry:
Conclusion
So, as you can see it’s super easy to connect from your Rails application to the DynamoDB instanse running on AWS.
Happy coding!