Help us understand the problem. What is going on with this article?

Sinatra 入門

More than 3 years have passed since last update.

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では

main.rb
get "/" do
  erb :index
end

index.erbでは

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部分に該当するのを書く

main.rb
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

layout.erb
<!DOCTYPE html>
<html lang="ja">
<head>
  <mata charset="utf-8">
  <title><%= title %></title>
</head>
<body>
    <%= yield %>
</body>
</html>
index.erb
<div><%= @content %></div>
about.erb
<div><%= @content %></div>
<div><%= @email %></div>

09 before/afterフィルタを使おう

レイアウトにたよらない方法!

main.rb
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

のなかに関数の定義を追加する。
実例↓

main.rb
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の勉強必要

下準備

sinatra_lessons>main.rb
require "sinatra"
require "sinatra/reloader"

get "/" do 
    erb :index
end
sinatra_lessons>index.erb
<!DOCTYPE html>
<html lang="ja">
<head>
    <mata charset="utf-8">
    <title><%= @title%></title>
</head>
<body>
    <div> <%= @content %></div>
</body>
</html>
import.sql
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変数にデータベースの中身を入れる

sinatra_lessons>main.rb
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 コメントの一覧を表示させよう

変数の中身を表示する場合<%= %>
制御文の場合<% %>

sinatra_lessons>index.erb
<!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コメントを投稿

データベースにデータがないので投稿するためのフォームを作る

sinatra_lessons>index.erb
<!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>

フォームに何かを入れると登録されるようにする

main.rb
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機能を使い、コメントを削除できるようにしていきます。

sinatra_lessons>index.erb
<!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

データベースからコメントを削除する機能を実現する

main.rb
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 エスケープ処理

悪意のあるコードを入力された時にエスケープする

main.rb
helpers do
    include Rack::Utils
    alias_method :h,:escape_html
end
sinatra_lessons>index.erb
<!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>
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away