この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
AWS::Record::HashModel
AWS SDK for Ruby で DynamoDB を使うと思い、ググってみると AWS::DynamoDB クラスを使っているサンプルがほとんどでした。しかし SDK の中に AWS::Record::HashModel という DynamoDB のための便利な Model クラスを発見し、これはと思い使ってみたところとっても簡単に実装できました。
class Task < AWS::Record::HashModel
string_attr :name
end
task = Task.new(:name => "My Sample Task")
task.name #=> 'My Sample Task'
シンプルなタスク管理アプリを作ってみる
Rails アプリのひな形をつくる
ということで Model に AWS::Record::HashModel クラスを用いた、シンプルなタスク管理アプリを作ってみたいと思います。まずはこちらの記事を参考に、Rails アプリのひな形を作ります。
mkdir my-simple-todos && cd my-simple-todos
bundle init
vim Gemfile # gem 'rails' をコメントアウトする
bundle install
bundle exec rails new . --skip-bundle
AWS サービスを使えるようにする
次に AWS SDK を Gemfile に追加します。また Bootstrap で実装したいので bootstrap-sass も追加しました。
vim Gemfile # gem 'aws-sdk' と gem 'bootstrap-sass' を追加する
bundle install
vim app/config/aws.yml
aws.yml は AWS の設定ファイルです。以下のように記述します。
app/config/aws.yml
development:
access_key_id: 'YOUR_ACCESS_KEY_ID'
secret_access_key: 'YOUR_SECRET_ACCESS_KEY'
dynamo_db_endpoint: 'dynamodb.ap-northeast-1.amazonaws.com'
test:
access_key_id: 'YOUR_ACCESS_KEY_ID'
secret_access_key: 'YOUR_SECRET_ACCESS_KEY'
dynamo_db_endpoint: 'dynamodb.ap-northeast-1.amazonaws.com'
production:
access_key_id: 'YOUR_ACCESS_KEY_ID'
secret_access_key: 'YOUR_SECRET_ACCESS_KEY'
dynamo_db_endpoint: 'dynamodb.ap-northeast-1.amazonaws.com'
ここまでで AWS を扱えるようになりました。
実装する
あとはモデル・ビュー・コントローラーを実装していきましょう。ちなみにモデルクラスを生成するときですが migration は不要なので無効にしています。
# model の作成
bundle exec rails g model task \
id:integer name:string end_time:timestamp --migration=false
# view, controller の作成
bundle exec rails g controller tasks index
モデルをつくる
モデルのクラスは AWS::Record::HashModel を継承します。あとは string_attr で属性を作っていきます。他の型を使いたい場合は boolean_attr や date_attr などがあるのでそちらを使いましょう。また timestamps メソッドを入れると created_at と updated_at という属性を付けてくれます。楽ちんですね!
app/model/task.rb
class Task < AWS::Record::HashModel
string_attr :name
timestamps
end
[/ruby]
</p>
<h4>コントローラーをつくる</h4>
<p>
コントローラーは index, create, destroy を実装しました。<br />
index ではテーブル内の全てのレコードを取得しています。そのままではデータがバラバラに入ってきてしまうので created_at でソートしています。また create では input に入力された前提でパラメータを Task モデルに渡して保存しています。そのときテーブルが存在しない場合は rescue でキャッチしてテーブルを作るような処理も書きました。
</p>
<p>
<strong>app/controller/tasks_controller.rb</strong><br />
# coding: utf-8
class TasksController < ApplicationController
def index
# created_at でソート
@tasks = Task.all.sort{ |a, b| a.created_at <=> b.created_at }
end
def create
task = Task.new(params[:task])
task.save
redirect_to :back, notice: 'Created New Task.'
rescue AWS::DynamoDB::Errors::ResourceNotFoundException
# テーブルが存在しない場合は作成してリダイレクト
Task.create_table 1, 1
redirect_to :back, alert: 'Sorry, Try again.'
end
def destroy
task = Task.find_by_id(params[:id])
task.delete
redirect_to :back, notice: 'Deleted Task.'
end
end
routes も忘れずに設定しましょう。
config/routes.rb
MySimpleTodos::Application.routes.draw do
resources :tasks, only: [:index, :create, :destroy]
end
ビューをつくる
最後にビューを作って終わりです。特に特別なことはしていません。。 注意点としては Task モデルは ActiveRecord ではないので form_for メソッドは使えません。今回はその代わりに form_tag メソッドで実装しています。 created_at は見やすいようにフォーマットかけてみました。
app/view/tasks/index.html.erb
<div class="container">
<h1>MyTasks</h1>
<!-- 操作が成功したときに表示する -->
<% if notice %>
<p class="alert alert-success">
<a class="close" data-dismiss="alert">×</a>
<%= notice %>
</p>
<% end %>
<!-- 操作が失敗したときに表示する -->
<% if alert %>
<p class="alert alert-error">
<a class="close" data-dismiss="alert">×</a>
<%= alert %>
</p>
<% end %>
<!-- 入力フォーム -->
<div>
<%= form_tag({:controller => :tasks, :action => :create}, {:class => "input-append"}) do %>
<%= text_field_tag "task[name]", "", :id => "task_name" %>
<%= submit_tag "ADD", :class => "btn" %>
<% end %>
</div>
<!-- アイテム一覧 -->
<div>
<table class="table table-striped table-bordered">
<tbody>
<tr>
<th>Name</th>
<th>CreatedAt</th>
<th>UpdatedAt</th>
<th>Done</th>
</tr>
<% @tasks.each do |task| %>
<tr>
<td><%= task.name %></td>
<td class="span3">
<%= task.created_at.strftime('%Y/%m/%d %H:%M:%S') %>
</td>
<td class="span3">
<%= task.updated_at.strftime('%Y/%m/%d %H:%M:%S') %>
</td>
<td class="span1">
<%= button_to 'Done', { :action => "destroy", :id => task.id }, method: :delete, class: 'btn btn-small btn-primary' %>
</td>
</tr>
<% end %>
</tbody>
</table>
</div>
</div>
alert を使ったので bootstrap-alert も読み込みます。
app/assets/javascripts/application.js
//= require jquery
//= require jquery_ujs
//= require bootstrap-alert
//= require_tree .
動かしてみる
これでひと通り完成しました。起動してみましょう!
bundle exec rails s
アイテムの追加・削除・一覧ができます。追加・削除の動作がかなり軽快に動くと思います!
ManagementConsole から DynamoDB の中身を直接見てみても、もちろんちゃんと格納されています。
ソースコード
今回つくったアプリを GitHub で公開しました。ご自由にお使いください〜。
まとめ
AWS::Record::HashModel を使うと Dynamo DB のモデルが簡単にできるよ!というお話でした。ちなみに Simple DB は AWS::Record::Model を使うと楽に実装できそうです!