[Ruby on Rails] AWS::Record::HashModel を使って Amazon DynamoDB のモデルを作る
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 を使うと楽に実装できそうです!