Sinatra
MongoDB
Sinatra
MongoDB
Powered by Rabbit 2.1.2 and COZMIXNGSinatraとMongoDB
今回はSinatraでMongoDBの操作 を体験してみます。 進捗に合わせて、ドライバから Rubyで使える便利なORMの紹介を します。SinatraとMongoDB
まずは初回なのでSinatraの基本か
Hello world
require 'sinatra'
get '/' do
"Hello, world!"
Hello world
これは最も単純で有名な例ですが、 HTTPヘッダを見てみましょう。
Hello world
ブラウザにはこういったヘッダーの 情報を確かめる機能が備わっていま す。 その中でも重要なのがRequest MethodがGETであるという点で す。HTTP Method
これらのGETはHTTP Methodの一
部で、主にGETやPOSTが使われて
います
GET POST PUT DELE
TE OPTION 何か 見せ る 何か 生成 する 何か 更新 する 何か 削除 する 何か 満た す http://www.sinatrarb.com/intro-ja.html より引用
POST
では、次にpostメソッドを試して みましょう require 'sinatra' post '/' do "Hello world!" endPOST
$ curl -X POST http://localhost:4567
POST
require 'sinatra' post '/' do "Hello world!" end get '/' do erb <<EOF<form method='post' action='/'> <input type='submit' /> </form>
EOF
POST
ただし、POSTコマンドは通常では
値の取得には用いません
値を取得するときにはGETを使い
MongoDB
それでは実際にデータを保存するた
MongoDB
インストールは行ってきましたか? $ which mongo
MongoDB
まずは基本から。
$ mongo # クライアントの起動 > db # 現在のテーブル
> use foo # foo をこれから使用(この時点ではまだ書き込まれていない) > db # foo
MongoDB
外部接続の場合。
MongoDB
まずは基本から。 > a = { name: 'Frank' }
> db.sinatraDB.insert(a) # 挿入
> show collections # sinatraDBが書き込まれている > db.sinatraDB.find() # 検索
MongoDB
$ gem install mongo bson_ext bson_extはmongoライブラリに BSON形式をサポートさせるための Gemです
MongoDB
require 'sinatra'
require 'mongo'
include Mongo # Mongoの省略
configure do
conn =MongoClient.new # localhost:27017
set connection: conn
set db: conn.db('foo') # use foo
end
get '/collections' do
settings.db.collection_names.to_a.to_s # show collections と同じ
MongoDB
require 'sinatra' require 'mongo' get '/' do
# ドキュメント全体
settings.db['sinatraDB'].find.to_a.to_s
end
get '/:collection' do |col|
# name が collectionであるものをひとつ返す
settings.db['sinatraDB'].find_one(name: col).to_s
Haml
テンプレートエンジンを使います $ gem install haml
Haml
テンプレートエンジンを使います
get '/' do
haml :index
Haml
./views/index.haml
%form{action: '/', method: 'post'}
%input{name: 'name', placeholder: 'name'} %input{type: 'submit'}
注意:インデント幅はソフトスペー
MongoDB
Sinatraからデータを登録します
post '/' do
bson_id = settings.db['sinatraDB'].insert(params) bson_id.to_s
end
MongoDB
BSON_IDからの検索?
get '/id/:id' do |id|
settings.db['sinatraDB'].find(id).to_s
MongoDB
BSON_IDからの検索
get '/id/:id' do |id|
id = BSON::ObjectId.from_string(id)
settings.db['sinatraDB'].find(id).to_s
ヘルパー
helpers do def foo 'baz' end endヘルパー
または module Foo def foo 'baz' end end helpers Fooヘルパー
# Haml, Slim = foo
# ERB
ヘルパー
helpers do
def find_by_name(name)
settings.db['sinatraDB'].find(name: name)
end
def find_all
settings.db['sinatraDB'].find
end
ヘルパー
= find_by_name.count
%ul
- find_by_name('Frank').each do |document|
データの更新
./views/index.haml %ul
- find_all.each do |document| %li
データの更新
ルーティング get '/update/:id' do |id| @id = id haml :update endデータの更新
./views/update.haml
%h1= find_by_id(@id)
%form{action: "/update/#{@id}", method: 'post'}
%input{name: 'name', value: find_by_id(@id)}
データの更新
ヘルパー
helpers do
def find_by_id(id)
id = BSON::ObjectId.from_string(id)
settings.db['sinatraDB'].find_one(id)['name'] end
データの更新
post '/update/:id' do |id|id = BSON::ObjectId.from_string(id)
settings.db['sinatraDB'].update({_id: id}, params) redirect '/'
データの削除
./views/index.haml
%ul
- find_all.each do |document| %li
= document['name'] |
%a{href: "/update/#{document['_id']}"} 更新 |
データの削除
ルーティング
get '/delete/:id' do |id|
id = BSON::ObjectId.from_string(id)
settings.db['sinatraDB'].remove(_id: id)
redirect '/' end
本来はPOSTを使うのですが、今回
は操作感を重視してGETを使いま
データの追加
はじめに追加した部分もredirectに
書き換えましょう
post '/' do
settings.db['sinatraDB'].insert(params)
redirect '/' end
未完了と完了
ようやくToDoリストを作り始める
基礎をおさえることができました。 今度はそれぞれのタスクが完了して いるかどうかを判断させます。
未完了と完了
./views/index.haml
%ul
- find_all.each do |document| %li
- if document['status']
%s= document['name']
|
%a{href: "/delete/#{document['_id']}"} 削除 - else
= document['name']
|
%a{href: "/done/#{document['_id']}"} 完了 |
%a{href: "/update/#{document['_id']}"} 更新 |
未完了と完了
= document['status'].class.to_s #=> NilClass
nil(空白)が返ってくるのでエラーに ならない
未完了と完了
ルーティング
get '/done/:id' do |id|
id = BSON::ObjectId.from_string(id) settings.db['sinatraDB'].update( {_id: id},
{ "$set" => {status: Time.now} } )
redirect '/' end