【ドットインストール】Sinatra入門
ドットインストールのSinatra入門を見てみました。
http://dotinstall.com/lessons/basic_sinatradotinstall.com
こないだBOTを作成するときに、久しぶりにSinatraを触ったので復習がてらですね。
yamano3201.hatenablog.jp
環境
➜ sinatra ruby -v ruby 2.2.2p95 (2015-04-13 revision 50295) [x86_64-darwin14] ➜ sinatra gem -v 2.6.3 ➜ sinatra gem list activerecord *** LOCAL GEMS *** activerecord (4.2.6, 4.2.1, 4.0.1) activerecord-deprecated_finders (1.0.4, 1.0.3) ➜ sinatra gem list sqlite3 *** LOCAL GEMS *** sqlite3 (1.3.10) ➜ sinatra gem list sinatra *** LOCAL GEMS *** sinatra (1.4.7, 1.4.6) sinatra-contrib (1.4.7)
sinatra-contribをインストールして、require 'sinatra/reloader' しておきましょう。
コード修正するたびにSinatraの再起動が不要になるので便利です。
http://webcreator.weva.jp/ruby/903webcreator.weva.jp
実行方法
ruby main.rb -o localhost
あとはブラウザからアクセスするだけ。デフォルトは4567ポート。
パラメータを使う
require 'sinatra' require 'sinatra/reloader' # http://localhost:4567/about get '/about' do "about this site page" end # http://localhost:4567/hello/kenta/yamano # ?で挟んだパラメータであるname1, name2はなくても良い get '/hello/?:name1?/?:name2?' do |name1, name2| "hello #{name1} #{name2}" end # http://localhost:4567/from/hokkaido/to/tokyo # *はなんでも良い get '/from/*/to/*' do |from, to| "from #{from} to #{to}" end # http://localhost:4567/users/555 # [0-9]* には数字の連続が入る get %r{/users/([0-9]*)} do |i| "user id = #{i}" end
テンプレートファイルを使う
require 'sinatra' require 'sinatra/reloader' # before処理は他の処理が始まる前に実行される before do @author = "yamano" end # after処理は他の処理が始まる前に実行される # logger.infoで指定した文字列はsinatraを立ち上げている画面で出力される after do logger.info "page displayed successfully" end # よく使う処理はhelpersに登録しておくと便利 helpers do def strong(s) "<strong>#{s}</strong>" end end # http://localhost:4567/about # views/about.erb ファイルを開く # strongはhelpersで定義してある get '/about' do @title = "about this page" @content = "this page is ... by " + strong(@author) @email = "xxx@gmail.com" erb :about end # http://localhost:4567/yamano # views/index.erb ファイルを開く # strongはhelpersで定義してある get '/:name' do |n| @name = n @title = "Sinatra入門" @content = "main content by " + strong(@author) erb :index end
viewsフォルダの下にあるerbファイルを呼び出すことができます。それぞれabout.erbファイルとindex.erbファイルを呼び出しています。
views/about.erb
<div><%= @content %></dv> <div><%= @email %></dv>
views/index.erb
<h1>Hello <%= @name %></h1> <div><%= @content %></dv>
erbファイルの共通部分はlayout.erbに書き出すことができます。
yieldの部分でindex.erbやabout.erbを呼んでいます。
views/layout.erb
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="utf-8"> <title><%= @title %></title> </head> <body> <%= yield %> </body> </html>
掲示板アプリを作る
上で学んだことを使いつつ、コメントの一覧表示、作成、削除を行える簡単なアプリを作ります。
掲示板アプリではDBを使うので、事前にsqlファイルからtableを作成しておきます。
import.sql
create table comments ( id integer primary key, body text );
.read で上のファイルをインポートします。
sqlite3 bbs.db SQLite version 3.8.5 2014-08-15 22:37:57 Enter ".help" for usage hints. sqlite> .read import.sql sqlite> .schema CREATE TABLE comments ( id integer primary key, body text ); sqlite> quit;
ここからrubyファイル。
require 'sinatra' require 'sinatra/reloader' require 'active_record' # 使用するDBを宣言 ActiveRecord::Base.establish_connection( "adapter" => "sqlite3", "database" => "./bbs.db" ) class Comment < ActiveRecord::Base end # 入力にスクリプトが埋め込まれても実行されないようにエスケープする。 # erbファイルの入力のところでhを挿入することでエスケープできる。 helpers do include Rack::Utils alias_method :h, :escape_html end # 一覧表示。@commentsにコメント一覧が入っている。erbファイルではこれを呼び出す。 get '/' do @comments = Comment.order("id desc").all erb :index2 end # bodyをキー、erbファイルで入力されたparams[:body]をバリューにしてDBに格納している post '/new' do Comment.create({:body => params[:body]}) redirect '/' end # 削除。idで削除。 post '/delete' do Comment.find(params[:id]).destroy end
削除のところでは、jQueryを使っています。
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="utf-8"> <title>BBS</title> </head> <body> <h1>BBS</h1> <ul> <% @comments.each do |comment| %> <li data-id="<%= comment.id %>"> <%= h comment.body %> <span class="deleteCmd" style="cursor:pointer;color:blue">[x] </li> <% end %> </ul> <h2>Add New</h2> <form method="post" action="/new"> <input type="text" name="body"> <input type="submit" value="post!"> </form> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.2/jquery.min.js"></script> <script> $('.deleteCmd').click(function(){ var el = $(this).parent(); if (confirm('are you sure to delete?')) { $.post('/delete', { id: el.data('id') }, function() { el.fadeOut(800); }) } }) </script> </body> </html>
これで簡単なアプリが動きます。