Rubyを使ったウェブサービスの作成はRuby on Railsが有名らしい
調べたところRailsは機能フル装備で中上級者用とあったので軽量のSinatraというパッケージを利用する。
参考: たった5行のコードでWebサービス!Sinatra, Rubyとは?
引用: Sinatra入門 (全17回) - ドットインストール
#01 Sinatraとはなにか?
Mac-no-MacBook-Pro:~ Mac$ gem install sinatra
待機なげえ
Fetching: rack-1.6.0.gem (100%)
Successfully installed rack-1.6.0
Fetching: tilt-1.4.1.gem (100%)
Successfully installed tilt-1.4.1
Fetching: rack-protection-1.5.3.gem (100%)
Successfully installed rack-protection-1.5.3
Fetching: sinatra-1.4.5.gem (100%)
Successfully installed sinatra-1.4.5
Parsing documentation for rack-1.6.0
Installing ri documentation for rack-1.6.0
Parsing documentation for rack-protection-1.5.3
Installing ri documentation for rack-protection-1.5.3
Parsing documentation for sinatra-1.4.5
Installing ri documentation for sinatra-1.4.5
Parsing documentation for tilt-1.4.1
Installing ri documentation for tilt-1.4.1
Done installing documentation for rack, rack-protection, sinatra, tilt after 211 seconds
4 gems installed
Mac-no-MacBook-Pro:~ Mac$ gem install sqlite3
Building native extensions. This could take a while...
Successfully installed sqlite3-1.3.10
Parsing documentation for sqlite3-1.3.10
Done installing documentation for sqlite3 after 0 seconds
1 gem installed
Mac-no-MacBook-Pro:~ Mac$ gem install sinatra-contrib
Fetching: backports-3.6.4.gem (100%)
Successfully installed backports-3.6.4
Fetching: rack-test-0.6.3.gem (100%)
Successfully installed rack-test-0.6.3
Fetching: multi_json-1.10.1.gem (100%)
Successfully installed multi_json-1.10.1
Fetching: sinatra-contrib-1.4.2.gem (100%)
Successfully installed sinatra-contrib-1.4.2
Parsing documentation for backports-3.6.4
Installing ri documentation for backports-3.6.4
Parsing documentation for multi_json-1.10.1
Installing ri documentation for multi_json-1.10.1
Parsing documentation for rack-test-0.6.3
Installing ri documentation for rack-test-0.6.3
Parsing documentation for sinatra-contrib-1.4.2
Installing ri documentation for sinatra-contrib-1.4.2
Done installing documentation for backports, multi_json, rack-test, sinatra-contrib after 2 seconds
4 gems installed
Mac-no-MacBook-Pro:~ Mac$ gem install activerecord
Fetching: thread_safe-0.3.4.gem (100%)
Successfully installed thread_safe-0.3.4
Fetching: minitest-5.5.1.gem (100%)
Successfully installed minitest-5.5.1
Fetching: tzinfo-1.2.2.gem (100%)
Successfully installed tzinfo-1.2.2
Fetching: i18n-0.7.0.gem (100%)
Successfully installed i18n-0.7.0
Fetching: activesupport-4.2.0.gem (100%)
Successfully installed activesupport-4.2.0
Fetching: builder-3.2.2.gem (100%)
Successfully installed builder-3.2.2
Fetching: activemodel-4.2.0.gem (100%)
Successfully installed activemodel-4.2.0
Fetching: arel-6.0.0.gem (100%)
Successfully installed arel-6.0.0
Fetching: activerecord-4.2.0.gem (100%)
Successfully installed activerecord-4.2.0
Parsing documentation for activemodel-4.2.0
Installing ri documentation for activemodel-4.2.0
Parsing documentation for activerecord-4.2.0
Installing ri documentation for activerecord-4.2.0
Parsing documentation for activesupport-4.2.0
Installing ri documentation for activesupport-4.2.0
Parsing documentation for arel-6.0.0
Installing ri documentation for arel-6.0.0
Parsing documentation for builder-3.2.2
Installing ri documentation for builder-3.2.2
Parsing documentation for i18n-0.7.0
Installing ri documentation for i18n-0.7.0
Parsing documentation for minitest-5.5.1
Installing ri documentation for minitest-5.5.1
Parsing documentation for thread_safe-0.3.4
Installing ri documentation for thread_safe-0.3.4
Parsing documentation for tzinfo-1.2.2
Installing ri documentation for tzinfo-1.2.2
Done installing documentation for activemodel, activerecord, activesupport, arel, builder, i18n, minitest, thread_safe, tzinfo after 16 seconds
9 gems installed
#02 はじめてのSinatra
ターミナルでruby main.rb
Mac-no-MacBook-Pro:sinatora_lessons Mac$ ruby main.rb
[2015-01-31 00:57:53] INFO WEBrick 1.3.1
[2015-01-31 00:57:53] INFO ruby 2.1.2 (2014-05-08) [x86_64-darwin14.0]
== Sinatra/1.4.5 has taken the stage on 4567 for development with backup from WEBrick
[2015-01-31 00:57:53] INFO WEBrick::HTTPServer#start: pid=62144 port=4567
127.0.0.1 - - [31/Jan/2015:00:58:19 +0900] "GET / HTTP/1.1" 200 11 0.0091
localhost - - [31/Jan/2015:00:58:19 JST] "GET / HTTP/1.1" 200 11
- -> /
127.0.0.1 - - [31/Jan/2015:00:58:20 +0900] "GET /favicon.ico HTTP/1.1" 404 448 0.0009
localhost - - [31/Jan/2015:00:58:20 JST] "GET /favicon.ico HTTP/1.1" 404 448
http://127.0.0.1:4567/ -> /favicon.ico
#03 複数のリクエストに対応してみよう
いちいちwebrickを再起動するのはめんどくさいから
require “sinatra/reloader”
これはgem install sinatra-contrib
のおかげ
#04 URLからのパラメータを使おう (1)
URLから渡されたパラメータ :name
コロンの後に変数をつけてシンボルにする
それを使うには、文字列の中で変数を展開するには、#{params[シンボル、:変数]}
get "/hello/:name" do
"hello #{prams[:name]}”
end
params=
パラメーターズの意味
params[]
をいちいち書くのが面倒な時は
get "/hello/:name" do |n|
"hello #{n}"
end
ブロックを使えばいい
またパラメーターは2つ以上設定でき|f,l|
のようにする
またパラメーターをオプションにしたい時は
get "/hello/:fname/?:lname?” do |f,l|
"hello #{f} #{l}"
end
シンボル?のようにする
#05 URLからのパラメータを使おう (2)
ワイルドカード *
何でも
正規表現%r{}
[0-9]*
数字、0-9の繰り返し
正規表現にマッチした場合表示される
#06 ERBテンプレートを使おう
viewsのフォルダを作る
その下にindex.erb
main.rbでは
get "/" do
erb :index
end
index.erbでは
<!DOCTYPE html>
<html lang="ja">
<head>
<mata charset="utf-8">
<title>sinatra</title>
</head>
<body>
<h1>heloo</h1>
</body>
</html>
#07 テンプレートで変数を使ってみよう
受け取ったパラメーターをテンプレート(views)に反映させる(index.erb)には@name
などに代入する
テンプレートに変数の値を表示させたい場合、@がついた変数名を<%= %>
で囲む
=>@
がついた変数名はテンプレートで使える
#08 layout.erbを使ってみよう
テンプレートが多くなった時にviewsフォルダにlayout.erbを作る
共通部分以外を<%= yield%>
にする
*layout.erbにはviews各ファイルで共通する部分を入れる。
*viewsの各レイアウト(index.erbやabout.erb)にはlayout.erb
のyield部分に該当するのを書く
require = 'sinatra'
require = 'sinatra/reloader'
get "/" do
@title = "main"
@content = "main contnt"
erb :index
end
get "/about" do
@title = "about"
@content = "about contnt"
@email = 'mail@k.com'
erb :about
end
<!DOCTYPE html>
<html lang="ja">
<head>
<mata charset="utf-8">
<title><%= title %></title>
</head>
<body>
<%= yield %>
</body>
</html>
<div><%= @content %></div>
<div><%= @content %></div>
<div><%= @email %></div>
#09 before/afterフィルタを使おう
レイアウトにたよらない方法!
require = 'sinatra'
require = 'sinatra/reloader'
1.before do
@author = "kimioka"
end
2.before '/admin/*' do
@msg = "admin area"
end
3.after do
logger.info "page displayed"
end
get "/" do
@title = "main"
@content = "main contnt" + @author
erb :index
end
get "/about" do
@title = "about"
@content = "about contnt"+ @author
@email = 'mail@k.com'
erb :about
end
#10 helperを使ってみよう
main.rbや各レイアウトでよく使う処理を登録
共通関数の定義でいろいろなところから使う
helpers do
end
のなかに関数の定義を追加する。
実例↓
require = 'sinatra'
require = 'sinatra/reloader'
before do
@author = "kimioka"
end
helpers do
def strong(a)
<strong> #{a} </strong>
end
end
get "/" do
@title = "main"
@content = "main contnt" + strong(@author)
erb :index
end
#11 掲示板アプリを作ってみよう
データベースの設定
sqlの勉強必要
下準備
require "sinatra"
require "sinatra/reloader"
get "/" do
erb :index
end
<!DOCTYPE html>
<html lang="ja">
<head>
<mata charset="utf-8">
<title><%= @title%></title>
</head>
<body>
<div> <%= @content %></div>
</body>
</html>
create table comments(
id integer primary key,
body text
);
bbs.dbを作成、import.sqlの読み込み
sinatora_lessons Mac$ 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> select * from comments;
#12 ActiveRecordを使ってみよう
データベースの設定ができたのでActiveRecordを使って読み出す
active_recordってなに
@comments変数にデータベースの中身を入れる
require "sinatra"
require "sinatra/reloader"
require 'active_record'
ActiveRecord::Base.establish_connection(
"adapter" => "sqlite3",
"database" => "./bbs.db"
)
class Comment < ActiveRecord::Base
end
get "/" do
@comments = Comment.order("id desc").all
erb :index
end
#13 コメントの一覧を表示させよう
変数の中身を表示する場合<%= %>
制御文の場合<% %>
<!DOCTYPE html>
<html lang="ja">
<head>
<mata charset="utf-8">
<title>BBS</title>
</head>
<body>
<h1>BBS</h1>
<ul>
<% @comments.each do |comment| %>
<li data-id= "<%= comment.id %>">
<%= comment.body %>
</li>
<% end %>
</ul>
</body>
</html>
#14コメントを投稿
データベースにデータがないので投稿するためのフォームを作る
<!DOCTYPE html>
<html lang="ja">
<head>
<mata charset="utf-8">
<title>BBS</title>
</head>
<body>
<h1>BBS</h1>
<ul>
<% @comments.each do |comment| %>
<li data-id= "<%= comment.id %>">
<%= comment.body %>
</li>
<% end %>
</ul>
<h2>Add new</h2>
<form method="post" action="/new">
<input type= "text" name="body"><input type= "submit" value="post!">
</form>
</body>
</html>
フォームに何かを入れると登録されるようにする
require "sinatra"
require "sinatra/reloader"
require 'active_record'
ActiveRecord::Base.establish_connection(
"adapter" => "sqlite3",
"database" => "./bbs.db"
)
class Comment < ActiveRecord::Base
end
get "/" do
@comments = Comment.order("id desc").all
erb :index
end
post "/new" do
Comment.create({:body => params[:body]})
redirect '/'
erb :index
end
#15 コメントを削除してみよう (1)
jQueryのAjax機能を使い、コメントを削除できるようにしていきます。
<!DOCTYPE html>
<html lang="ja">
<head>
<mata charset="utf-8">
<title>BBS</title>
</head>
<body>
<h1>BBS</h1>
<ul>
<% @comments.each do |comment| %>
<li data-id= "<%= comment.id %>">
<%= comment.body %>
</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.11.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>
#16コメントを削除してみよう2
データベースからコメントを削除する機能を実現する
require "sinatra"
require "sinatra/reloader"
require 'active_record'
ActiveRecord::Base.establish_connection(
"adapter" => "sqlite3",
"database" => "./bbs.db"
)
class Comment < ActiveRecord::Base
end
get "/" do
@comments = Comment.order("id desc").all
erb :index
end
post "/new" do
Comment.create({:body => params[:body]})
redirect '/'
erb :index
end
post'/delete' do
Comment.find(params[:id]).destroy
end
#17 エスケープ処理
悪意のあるコードを入力された時にエスケープする
helpers do
include Rack::Utils
alias_method :h,:escape_html
end
<!DOCTYPE html>
<html lang="ja">
<head>
<mata charset="utf-8">
<title>BBS</title>
</head>
<body>
<h1>BBS</h1>
<ul>
<% @comments.each do |comment| %>
<li data-id= "<%= comment.id %>">
>>> <%= h comment.body %>
</li>
<% end %>
</ul>
<h2>Add new</h2>
<form method="post" action="/new">
<input type= "text" name="body"><input type= "submit" value="post!">
</form>
</body>
</html>