Sinatraのルーティングと日本語URL
Sinatraのルーティングはシンプルでわかりやすい
そのうえ複雑なことも可能
今回はデータベースのデータをもとにして複数のページをつくってみた
その際、日本語URLも試した
目次
今回の環境
仮想環境の構築、データベースのインストールと設定は過去の記事参照
- 仮想環境
- OS
- Ubuntu 18.04
- データベース
- PostgreSQL 10.5
- Ruby 2.6.3
- bundler 2.0.2
- sinatra 2.0.5
- activerecord 5.2.3
ディレクトリ作成
テスト用ディレクトリ作成
routes_testというディレクトリをつくってそこへ移動
$ mkdir routes_test $ cd routes_test
Gemのインストール
Bundlerを使って必要なGemをインストールする。
Gemfileを作成
$ bundle init
GemfileにGemを記入
gem 'sinatra' gem 'sinatra-contrib' gem 'activerecord' gem 'pg'
bundleインストール
$ bundle install
アプリに必要なファイルをつくる
テンプレートはviewsディレクトリ内につくる
今回のテンプレートはErb
routes_test/main.rb
routes_test/views/index.erb
routes_test/views/club_info.erb
データベース作成
今回はPostgreSQLを使用
データベースを起動してrowingclubデータベース内にrowingclubsテーブルをつくる。
起動とデータベースの作成
$ sudo systemctl start postgresql $ createdb rowingclub
テーブル作成のSQLファイルをつくる。
create_rowingclubs.sql
create table rowingclubs ( id serial primary key, club_name varchar(20), created_at timestamp default current_timestamp, updated_at timestamp );
rowingclubデータベースにログイン
\i
コマンドでファイルからテーブルを作成する
$ psql rowingclub rowingclub=> \i create_rowingclubs.sql
テーブルにテスト用のレコードを挿入する
まずレコード挿入用のSQLファイルをつくる。
insert_record_to_rowingclub.sql
insert into rowingclubs (club_name) values ('ローイングクラブ'), ('ボートクラブ'), ('漕艇倶楽部'), ('端艇倶楽部');
\i
コマンドでファイルからレコードを挿入する
挿入後にテーブルからログアウト
rowingclub=> \i insert_record_to_rowingclub.sql rowingclub=> \q
できあがったテーブルの内容
rowingclub/rowingclubs
id | club_name |
---|---|
1 | ローイングクラブ |
2 | ボートクラブ |
3 | 漕艇倶楽部 |
4 | 端艇倶楽部 |
コーディング
main.rb
require 'sinatra' require 'sinatra/reloader' require 'active_record' #モデルの作成 class Rowingclub < ActiveRecord::Base establish_connection( adapter: 'postgresql', host: "", username: 'vagrant', password: "", database: 'rowingclub' ) def allclub allclub = Rowingclub.all return allclub end end #モデルの初期化と全レコードの抽出 allclub = Rowingclub.new.allclub #ルーティング #トップページ get '/' do @allclub = allclub erb :index end #モデルからeachメソッドでレコードを取り出して #各々のルートを作成 allclub.each do |club| #idのURLを作成 get "/#{club['id']}" do @club_name = club['club_name'] erb :club_info end #日本語のURLを作成 get "/#{club['club_name']}" do @club_name = club['club_name'] erb :club_info end end
index.erb
<!DOCTYPE html> <html lang="ja"> <head> <meta http-equiv="content-type" content="text/html" charset="utf-8"> <title>トップページ | Sinatra ルーティングテスト</title> </head> <body> <p>idでURLを作成</p> <ul> <% @allclub.each do |club| %> <li><a href=<%= "/#{club['id']}" %> ><%= "#{club['id']}" %></a></li> <% end %> </ul> <hr> <p>club_name(日本語)でURLを作成</p> <ul> <% @allclub.each do |club| %> <li><a href=<%= "/#{club['club_name']}" %> ><%= "#{club['club_name']}" %></a></li> <% end %> </ul> </body> </html>
club_info.erb
<!DOCTYPE html> <html lang="ja"> <head> <meta http-equiv="content-type" content="text/html" charset="utf-8"> <title>クラブ紹介ページ | Sinatra ルーティングテスト</title> </head> <body> <h1><%= "#{@club_name}の紹介ページ" %></h1> </body> </html>
実行する
$ ruby main.rb -o [ipアドレス]
WEBrickが立ち上がったらブラウで表示させる
ブラウザにipアドレスとポート番号を入力する
http://[ipアドレス]:4567
これでトップページが表示されれば成功
リンクをたどってページ遷移を確認
id(半角数字)のURL
日本語のURL
どちらもURLが期待通りになっている
URLエンコード
本来URLには非ASCII文字は使えないらしい
上で試したような場合はブラウザが日本語のURLをエンコードしてくれているのでエラーにならない
しかしredirectさせたりする場合は事前にURLエンコードが必要になる
URLエンコードするにはCGI.escape
メソッドを使う
CGI.escapeの使い方
require 'cgi' CGI.escape '変換したい文字列'
エラーになる例
redirect "/漕艇倶楽部" #=> ERROR URI::InvalidURIError: URI must be ascii only
URLエンコードをした例
require 'cgi' ja_url = "/漕艇倶楽部" ascii_url = CGI.escape ja_url redirect "#{ascii_url}" #=>エラーなくredirectする
参考ページ
Sinatra README
Routes
http://sinatrarb.com/intro.html
Rubyリファレンスマニュアル
CGIクラス
https://docs.ruby-lang.org/ja/latest/method/CGI/s/escape.html