ぱろっと・すたじお

技術メモなどをまったりと / my site : http://parrot-studio.com/

はじめてのSinatra

昨日、GAE絡みで初めてSinatraに触れて、
今回の仕事はこれで行こうと決めたので、
もうちょっと実用的なレベルで調べてみました


まず気に入ったのが、非常に軽量でシンプルであること


Sinatra自体は最低限のフレームワークを提供するだけなので、
その上に自分のフレームワークを構築しやすいのです
RailsRailsの作法に従わないといかんのが面倒で・・・


なにより、Sinatra自体のコードが、
Rackアプリのお手本ってくらいに綺麗で簡潔にできてます
これなら読むのも全然苦になりません(`・ω・´) b


以下、Sinatraのドキュメントや、自分で軽く実験した結果から、
後々使えそうな部分をメモ...φ(・ω・`)


もっと細かいことはドキュメントで
読みやすいので全体に目を通すとベスト
Sinatra: Documentation


チュートリアルは日本語版もあり
Sinatra: README (Japanese)


もっと具体的な例による解説
Ruby Freaks Lounge:第7回 小規模Webアプリのためのフレームワーク,Sinatra|gihyo.jp … 技術評論社
Ruby Freaks Lounge:第9回 SinatraとSequel・Hamlで掲示板アプリを作る|gihyo.jp … 技術評論社



とりあえず動かす方法

# app.rb
require 'rubygem'
require 'sinatra'

get '/' do
  "Hello World!"
end

# ruby app.rb

ルーティング

get '/user' do
  # from localhost:4567/user
end

post '/login/:name' do
  # post from localhost:4567/login/hoge
  p params[:name] #=> "hoge"
end

ワイルドカードもいける

get '/say/*/to/*' do
  # matches /say/hello/to/world
  # :splatで全部とれる
  params[:splat] # => ["hello", "world"]
end

get '/download/*.*' do
  # matches /download/path/to/file.xml
  params[:splat] # => ["path/to/file", "xml"]
end

正規表現すらOK

get %r{/hello/([\w]+)} do
  # :capturesで取れる
  "Hello, #{params[:captures].first}!"
end

複数のpathをまとめて処理

["/foo", "/bar", "/baz"].each do |path|
  get path do
    "You've reached me at #{request.path_info}"
  end
end

「/」の有無を気にしない場合

get '/info/?' do
  # "/info" or "/info/"
end

ルーティングは上から探索されるが明示的にpassもできる

get '/user/:name' do
  # for admin
  pass unless params[:name] == 'admin'
  # if not "admin" to next
end

get '/user/*' do
  # for user
  # if not from /user to next
end

get '/' do
  erb :index # トップページ
  # if not from / to next
end

get '/*' do
  # 知らないpathはエラーページへ
  # お探しのページは存在しません〜的な
  erb :not_found_error

  # indexへredirectでもいいかも
  # redirect '/'
end

ルーティングに一致しないって場合のもっと簡単な書き方

not_found do
  erb :not_found_error
end

エラーが発生した場合

error do
  erb :error
end

静的ファイルは/publicに置く

./public/test.html => localhost:4567/test.html

テンプレートは/viewに置く

get '/' do
  erb :index #=> ./view/index.erb
end

get '/user' do
  haml :user #=> ./view/user.haml
end

これらのPATHは変えられる

# myapp.rb
class MyApp < Sinatra::Base
  set :public, File.dirname(__FILE__) + '/static'    #=> ./public => ./static
  set :views,  File.dirname(__FILE__) + '/templates' #=> ./view => ./templates

  get '/' do
    erb :index #=> ./templates/index.erb
  end
end

# config.ru
require 'myapp'
run MyApp

# rackup config.ru

パラメータの受け渡し

# ./public/test.html
<html>
<head>
<title>Param Test</title>
</head>
<body>
<form action="/test" method="post">
<p> チェックボックスは[]をつける </p>
<input type="checkbox" name="q1[]" value="1">check1
<input type="checkbox" name="q1[]" value="2">check2<br />
<br />
<p> []をつけないと単体しか取れない </p>
<input type="checkbox" name="q2" value="1">check1
<input type="checkbox" name="q2" value="2">check2<br />
<br />
<p> radioに[]をつけると単体のArrayで返る </p>
<input type="radio" name="q3[]" value="1">check1
<input type="radio" name="q3[]" value="2">check2
<input type="radio" name="q3[]" value="3">check3<br />
<p> なので name="q3"でいい </p>
<input type="submit">
</form>
</body>
</html>
# test.rb
require 'rubygems'
require 'sinatra'

post '/test' do
  p params      #=> all params hash
  p params[:q1] #=> ["1", "2"] e.g.
  p params[:q2] #=> "1" or "2"
  p params[:q3] #=> ["3"] e.g.
end



一番重要なのは、Railsみたいに面倒な環境構築がいらんので、
こういった「実験」がさくさくできることですね
簡単な動作を確認するのに、いくつもファイルをいじるとか面倒ですし


しかも、あのPassengerで動くらしいので、
すでにRails用にPassengerを導入していれば、
あっという間に本番に適用できるのも素敵(*ノ∀ノ)


このように素晴らしいSinatraですが、
細かい部分まで見ていくと、結局はRackにたどり着きます


Sinatraのsessionはtrue/falseしか選べないので、
ちょっと不安だな・・・と思ったら、
やっぱりRackのを使うべきらしいです


Rackもいろいろ調べてみないとな・・・