先日、まちつく!が正式リリースになりました。よろしければ是非携帯でアクセスして遊んでみてください。
おはようございます。内田です。
今までRailsを使うほどでも無いアプリはオレオレフレームワークで作ってたのですが、最近巷で流行ってるsinatraのコードを読んでみたら必要十分な機能があり、センスも良く、とても気に入りました。
今回は公式ドキュメントの流れで、使いそうな機能をまとめてみました
一番簡単な例
sudo gem install sinatra
# app.rb require 'rubygems' require 'sinatra' get '/' do 'Hello, world' end
ruby app.rb curl http://localhost:4567/
Routes
HTTPメソッドにURLとブロックを渡します
get ‘/’ do
end
post ‘/’ do
end
put ‘/’ do
end
delete ‘/’ do
end
パラメータを含めたURLも可能
get ‘/hello/:name’ do
“Hello #{params[:name]}”
end
上記パラメータはブロック引数でも取れる
get ‘/hello/:name’ do |n|
“Hello #{n}”
end
ワイルドカードもつかえます
get ‘/say//to/’ do
- /say/hello/to/worldにアクセス
params[“splat”] # => [“hello”, "world]
end
?つきのパラメータやPOST等のパラメータはparams[:xxx]で取得できるよ
アプリケーションファイルは複数に分けることが可能。
読み込みにはrequireを使わずにloadを使うとdevelopmentモードの時に便利
require ‘rubygems’
require ‘sinatra’
get ‘/’ do
“Hello world”
end
load ‘more_routes.rb’
# more_routes.rb get '/foo' do "Foo" end
Handlers
Redirect
redirect ‘/’
redirect ‘http://www.google.co.jp’
redirect ‘/’, 303
redirect ‘/’, 307
Session
クッキーベースのセッション
有効にするにはTOPレベルか、configureブロックに書く
enable :sessions
get ‘/’ do
session[“count”] ||= 0
session[“count”] += 1
“count: #{session[‘count’]}”
end
Status
通常では200番のステータスコードになるがstatusメソッドをつかうと変更できる
get ‘/’ do
status 404
“Not found”
end
Filters
イベントの前に実行される
before do
end
before do new_params = {} params.each_pair do |full_key, value| this_param = new_params split_keys = full_key.split(/\]\[|\]|\[/) split_keys.each_index do |index| break if split_keys.length == index + 1 this_param[split_keys[index]] ||= {} this_param = this_param[split_keys[index]] end this_param[split_keys.last] = value end request.params.replace new_params end
<form> <input ... name="post[title]" /> <input ... name="post[body]" /> <input ... name="post[author]" /> </form>
{"post"=>{ "title"=>"", "body"=>"", "author"=>"" }}
views
Template Languages
viewファイルはroot/viewsに置きましょう
Haml,Sass,Erb,Builderがつかえる
- app.rb
get ‘/’ do
erb :index # views/index.erb
sass :styles # views/styles.sass
haml :index # views/index.haml
builder :index # views/index.builder
end
builderはブロックを使ってRSSを出力できたりする
サンプルプログラムが公式にあります。
Layouts
root/views/layout.{erb|haml|builder}
<%= yield %>
使いたくないときは
get ‘/’ do
erb :index, layout => false
end
アプリケーションと同じファイルにviewが書ける
が、個人的には使わない。公式参照
Models
sinatraはmodelを提供してないので、好きなのを使うとよろし
Sequelを使ってみる。
- app.rb
require ‘rubygems’
require ‘sinatra’
require ‘sequel’
Sequel::Model.plugin(:schema)
sequel.connect(‘sqlite://test.db’)
class Items < Sequel::Model
unless table_exista?
set_schema do
primary_key :id
string :name
timestamp :created_at
end
create_table
end
end
get ‘/’ do
@items = Items.all
erb :index
end
# views/index.erb <% for item in @items %> <div><%= item.name %></div> <% end %>
DatamapperやActiveRecordを使いたい場合は公式参照
API的なJSONでも出力してみる
require ‘json’
get ‘/api/items.json’ do
content_type :json
JSON.unparse(Items.all.map{|e|e.values})
end
Helpers
helpersブロックでメソッドを定義するとイベント内やテンプレートで使えます
helpers do
def bar(name)
“#{name}bar”
end
end
get ‘/:name’ do
bar(params[:name])
end
Rails的なpartialを定義
helpers do
def partial(page, options={})
erb page, options.merge!(:layout => false)
end
end
escape_html等のaliasを定義しとくと便利
helpers do
include Rack::Urils
alias_method :h, :escape_html
alias_method :u, :escape
end
Rack Middleware
useメソッドで指定しなさい
use Rack::Lint
get ‘/’ do
“hello”
end
Sinatra自体がいくつか読み込んでるので、重複するかもしれません。
Loggerとか。1リクエストでログが複数件でてビックリしました。
Error Handling
not_found
定義されてないURLにアクセスがあった場合に動作
not_found do
“Not found”
end
しかし、デフォルトのメッセージがセンス良すぎなので、production時にのみ定義したい。
error
例外が投げられたら動作
error do
‘error – ’ + request.env[’sinatra.error’].name
end
error MyCustomError do
‘So what happened was…’ + request.env[‘sinatra.error’].message
end
これもセンス良すぎなので次の方法でproduction時のみ動作にしましょう
configureメソッドをつかいます
configure :production do
not_found do
“Not found”
end
error do
“Error”
end
end
Configuration
configureブロックの中で変数を使う場合はsetをつかいましょう
configure :development do
set :dbname, ‘devdb’
end
configure :production do
set :dbname, ‘productiondb’
end
get ‘/whatdb’ do
’We are using the database named ’ + options.dbname
end
Deploy
個人的にはpassengerが良い
アプリケーションのrootディレクトリにtmp,publicディレクトリを作りconfig.ruを書く
#config.ru
require ‘app’
run Sinatra::Application
最新バージョンのrack(1.0)やpassennger(2.0.3)を使ったときのバグが公式に書いてありますので参照下さい。
参考
http://www.sinatrarb.com/
http://www.sinatrarb.com/book.html
http://www.sinatrarb.com/faq.html
http://www.sinatrarb.com/testing.html
http://www.sinatrarb.com/extensions.html
おしまい