仮想環境でSinatraアプリを起動する手順
目次
今回の環境
ホストOS: macOS 10.14.1
VirtualBox 5.2.20
Vagrant 2.1.2
Cyberduck 6.7.0
ゲストOS: Ubuntu 18.04
PostgreSQL 10.3
Ruby 2.5.1p57
Sinatra 2.0.3
ディレクトリ・ファイル
MyUbuntuディレクトリに仮想環境を作成
仮想環境内にSinatraAppディレクトリを作成
Sinatraアプリのファイル名はmain.rb
データベースはPostgreSQLを使用
Sinatraアプリを起動する手順
ターミナル/PowerShellで仮想環境ディレクトリに移動する
cd MyUbuntu
Vagrantを起動する
vagrant up
仮想環境にログインする(ssh接続する)
vagrant ssh
(PowerShellの場合はそのままではssh接続できないのでPuttyを起動して以後Puttyで操作)
Cyberduckを起動する
ファイルやディレクトリの作成、削除、読み込みはCyberDuckをつかう
Sinatraアプリが配置されているディレクトリに移動する
cd SinatraApp
PostgreSQLサーバを起動する
sudo systemctl start postgresql
Sinatraアプリ(サーバ)を起動する
(set :environment, :production
をSinatraコード内に記入している場合)
bundle exec ruby main.rb
(記入していない場合は-o [ipアドレス]
オプションをつけて起動する)
Sinatraアプリをブラウザで表示する
ブラウザのURL入力欄に
http://[ipアドレス]:[ポート番号]
と入力する
http://192.168.33.10:4567
(ipアドレスはVagrantfileの設定どおりに)
Sinatraアプリを終了する手順
Sinatraアプリ(サーバ)を停止する
controlキーとCキーを同時に押す
PostgreSQLサーバを終了する
sudo systemctl stop postgresql
Cyberduckを終了する
Cyberduckアプリを終了する
仮想環境からログアウトする
exit
Vagrantを終了する
vagrant halt
以上が仮想環境の起動・接続〜Sinatraアプリ起動、アプリ終了〜仮想環境の切断・終了までの手順
PostgreSQLに複数の外部ファイルを読み込ます方法
目次
外部ファイルを使ってレコードを一気に挿入
PostgreSQLをバージョンアップする方法がよくわかっていない。
データを移す方法がよくわからない。なので新バージョンをインストールするたびにレコードを挿入し直している。
バックアップ用のデータはinsert文をそのままSQLファイルにして保存してある。
外部ファイルを一つ一つ読み込ますのは面倒なので複数のファイルを一度に読み込ませている。
複数の外部ファイル
以下はresultデータベースのresultsテーブルに3年分のレース(レガッタ)結果を挿入する例。
次のような3つのファイルがあるとする。
2016result.sql
insert into results (year, rank, crew, time) values (2016,1,'Crew1','08:08.06'), (2016,2,'Crew2','08:11.24'), (2016,3,'Crew3','08:14.41');
2017result.sql
insert into results (year, rank, crew, time) values (2017,1,'Crew1','08:09.06'), (2017,2,'Crew2','08:12.24'), (2017,3,'Crew3','08:15.41');
2018result.sql
insert into results (year, rank, crew, time) values (2018,1,'Crew1','08:10.06'), (2018,2,'Crew2','08:13.24'), (2018,3,'Crew3','08:16.41');
上記3つのファイルを一度に読み込ますためのファイルをつくる。
results2016_2018.sql
\i 2016result.sql \i 2017result.sql \i 2018result.sql
PostgreSQLに複数の外部ファイルを読み込ます手順
- さきほどつくった4つのファイルを同じディレクトリに配置する
- ターミナル/PowerShellでファイルを配置したディレクトリに移動する
- PostgreSQLサーバを起動してresultデータベースに接続する
\i
コマンドでresults2016_2018.sqlファイルを読み込ます
以下はmacOS10での例。データベースへの接続方法は各環境ごとのものとする。
サーバを起動する
$ pg_ctl -D /usr/local/var/postgres -l logfile start
※-l logfile
はログを記録したい場合にお好みで。
resultデータベースに接続する
$ psql result
外部ファイルを読み込ます
result=# \i results2016_2018.sql
これで9件のレコードを一度に挿入できる。
今回の環境
macOS10.14
Ruby 2.5.1p57
PostgreSQL 10.3
Sinatraでよく使うツール その3
escape_htmlメソッド
スクリプトをエスケープするにはRack::Utilsのescape_htmlを使う。
メソッド名を変更する
escape_htmlメソッドはh
と名称を変えて使うことが多いらしい。
変更するにはalias_methodメソッドを使ったりdefで再定義する方法がある。
Sinatraではhelpersの中で定義するとどこでも呼び出せるようになる。
alias_methodを使って変更する
require 'sinatra' helpers do include Rack::Utils alias_method :h, :escape_html end
defで再定義
require 'sinatra' helpers do def h(text) Rack::Utils.escape_html(text) end end
使い方
実際にSinatraのコードを書いてみる。
今回の環境はVirtualBox Vagrant Ubuntu。
Sinatraはbundlerの--path
オプションでインストール。
main.rb
require 'sinatra' #-o [ipアドレス]オプションを不要にする set :environment, :production #escape_htmlをhに変更する helpers do include Rack::Utils alias_method :h, :escape_html end #もしくは次のコードでも同じ =begin helpers do def h(text) Rack::Utils.escape_html(text) end end =end #indexページを作成 get '/' do erb :index end #フォーム入力値を受け取って表示する post '/escape_test' do @str = params[:str] #エスケープして表示 "#{h @str}" end
viewsディレクトリの中にindex.erbを配置する。
このページで入力を受け付ける。
views/index.erb
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="utf-8"> </head> <body> <form action="escape_test" method="post"> <input type="text" name="str"> <button type="submit">submit</button> </form> </body> </html>
実行する
実行してみる。
main.rbの起動
bundle exec ruby main.rb
set :environment, :production
を使わない場合は-o
が必要。
bundle exec ruby main.rb -o 192.168.33.**
192.168.33.**にはVagrantfileで設定したipアドレスが入る。
ブラウザで確認する
ブラウザにURLを入力して表示する。
http://192.168.33.**:4567
http://localhost:4567
フォーム入力
次のようにstyleを入力してsubmitしてみる。
<span style="color: red;">ボート競技は最高!</span>
エスケープされると<span>
タグが文字列となって表示される。
<span style="color: red;">ボート競技は最高!</span>
こうなればエスケープ成功。
hがない場合
"#{h @str}"
を"#{@str}"
としてSinatraを再起動する。
先ほどと同じ文字列を入力してsubmitする。
ボート競技は最高!
hがないとstyleが有効になり赤い文字で表示されてしまう。
悪意のあるスクリプトはエスケープする必要がある。
ドキュメント
Rubyリファレンスマニュアル
class Module > #インスタンスメソッド
alias_method
https://docs.ruby-lang.org/ja/latest/class/Module.html
Sinatra Top > DOCS
FREQUENTLY ASKED QUESTIONS
How do I escape HTML?
http://sinatrarb.com/faq.html
Sinatraでよく使うツール その2
Sinatraのデフォルト設定では、publicという名のディレクトリ内にCSSなどの静的ファイルを配置するきまりになっている。
今回はこのディレクトリ名を変更する方法について試す。
目次
静的ファイル用のディレクトリ名を変更するコード
#publicをmystaticに変更する set :public_folder, File.dirname(__FILE__) + '/mystatic'
ディレクトリ名を変更するメリット
変更しておくとCSSファイルなどが外部からのぞかれにくくなる。
Sinatra Top > README > #Static Files
http://sinatrarb.com/intro.html
Note that the public directory name is not included in the URL. A file ./public/css/style.css is made available as http://example.com/css/style.css.
注意書きにあるようにpublicのままだとCSSファイルが表示されてしまうことがある。
名称を変更することでこれを防ぐ。
つかい方
今回の環境はVirtualBox Vagrant Ubuntu。
Sinatraはbundlerの--path
オプションでインストール。
コードをrequire
のつぎあたりに記入する。
main.rb
require 'sinatra' #-o [ipアドレス]オプションを不要にする set :environment, :production #publicをmystaticに変更する set :public_folder, File.dirname(__FILE__) + '/mystatic' get '/' do erb :index end
views/index.erb
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="utf-8"> <!-- リンクのパスはmystatic(public)の下層から記入 --> <link rel="stylesheet" href="/css/style.css" type="text/css" media="all"> </head> <body> <h1 class="red">レガッタはおもしろい</h1> </body> </html>
.red { color: red; }
ディレクトリ/ファイル構造
変更前
- main.rb - views - index.erb - public - css - style.css
変更後
- main.rb - views - index.erb - mystatic - css - style.css
実行
Sinatraファイルの起動
bundle exec ruby main.rb
set :environment, :production
を使わない場合は
bundle exec ruby main.rb -o 192.168.33.**
192.168.33.** にはVagrantfileで設定したipアドレスが入る。
ブラウザにURLを入力して表示
http://192.168.33.**:4567
http://localhost:4567
レガッタはおもしろい、と赤色の文字で表示されていれば成功。
Sinatraでよく使うツール
今回はローカル開発環境で使うと便利なコードについて。
目次
起動時に -o [ipアドレス]オプション が不要になるコード
set :environment, :production
つかい方
コードをrequire
のつぎあたりに記入する。
今回の環境はVirtualBox Vagrant Ubuntu。
Sinatraはbundlerの--path
オプションでインストール。
main.rb
require 'sinatra' set :environment, :production get '/' do 'Hello world' end
起動方法
main.rbを起動する。
bundle exec ruby main.rb
返答。
INFO WEBrick::HTTPServer#start done.
起動成功。
set :environment, :production
がない場合。
bundle exec ruby main.rb -o 192.168.33.**
のように-o [ipアドレス]
オプションが必要となる。
192.168.33.**
にはVagrantfileで設定したアドレスを入力する。
ブラウザーに表示
サーバーが起動したらブラウザに表示する。
下記のようにURLを入力すれば Hello world が表示される。
http://192.168.33.**:4567
Sinatraドキュメント
Sinatra Configuring Settings
Sinatra Top > DOCS > Configuring Settings
#Built-in Settings
:environment
http://sinatrarb.com/configuration.html
Heroku PostgresにSQLファイルを読み込ます
Heroku PostgresにはCSVファイルを挿入できないようなのでCSVファイルからinsert文のSQLファイルをつくる。
つくったSQLファイルをHeroku Postgresに読み込ませればレコードを挿入できる。
目次
- 前提条件
- CSVファイル
- Heroku Postgresのテーブル
- CSVファイルをSQLファイルに変換するコード
- 実行結果
- Heroku Postgres
- Heroku PostgresにSQL文を読み込ます
- 今回の動作確認環境
前提条件
Heroku Postgresを操作するにはローカルにもPostgreSQLがインストールされている必要がある。
Heroku上でデータベースとテーブルの設定を済ましておく。
CSVファイル
今回のサンプル
sample.csv
2018,全日本大学選手権,男子エイト,1,Aクルー,05:55.91 2018,全日本大学選手権,男子エイト,2,Bクルー,06:00.70 2018,全日本大学選手権,男子エイト,3,Cクルー,06:01.04 2018,全日本大学選手権,男子エイト,4,Dクルー,06:03.31
Heroku Postgresのテーブル
テーブル名: samples
Column | Type |
---|---|
id | integer |
year | smallint |
tournament_name | character varying(20) |
event_name | character varying(20) |
rank | smallint |
crew | character varying(20) |
goaltime | character varying(10) |
# idはserial primary key
CSVファイルをSQLファイルに変換するコード
rewrite.rb
require 'csv' class Sqlwriter def initialize(csv_file, sql_file) @csv_file = csv_file @sql_file = sql_file end def rewrite txt = "insert into samples (year,tournament_name,event_name,rank,crew,goaltime) values \n" CSV.foreach(@csv_file) do |csv_file| txt << "(#{csv_file[0]},'#{csv_file[1]}','#{csv_file[2]}',#{csv_file[3]},'#{csv_file[4]}','#{csv_file[5]}'),\n" end txt.gsub!(/,\Z/,";") open(@sql_file,"w") do |sql_file| sql_file.write txt end end end Sqlwriter.new("sample.csv","sample.sql").rewrite
実行結果
rewrite.rbとsample.csvを同じディレクトリに置いて実行する。
実行結果は次のとおり。
sample.sql
insert into samples (year,tournament_name,event_name,rank,crew,goaltime) values (2018,'全日本大学選手権','男子エイト',1,'Aクルー','05:55.91'), (2018,'全日本大学選手権','男子エイト',2,'Bクルー','06:00.70'), (2018,'全日本大学選手権','男子エイト',3,'Cクルー','06:01.04'), (2018,'全日本大学選手権','男子エイト',4,'Dクルー','06:03.31');
Heroku Postgres
Heroku PostgresのWebページ
Heroku Dev Center
Heroku Postgres
https://devcenter.heroku.com/articles/heroku-postgresql
Heroku PostgresにSQL文を読み込ます
Herokuにログインする前にターミナルのcd
コマンドでsample.sqlファイルがある場所に移動しておく。
移動したらHerokuにログインする。
heroku login #メールアドレスとパスワードが必要
Heroku Postgresにログインする。
heroku pg:psql --app [appname] #[appname]は各自のアプリ名
SQLファイルを読み込ませてデータベースにレコードを挿入する。
\i sample.sql
SQLファイルの内容が実行されてレコードが挿入される。
Heroku Postgresからログアウトする。
\q
Herokuからログアウトする。
heroku logout
今回の動作確認環境
条件分岐を1行にまとめる
目次
if文のみ
後置ifをつかう。
式 if 条件
event_name = 'エイト' # if 条件 式 end if event_name == 'エイト' puts "スイープ種目です。" end # 後置ifをつかう。 puts "スイープ種目です。" if event_name == 'エイト'
if文 else節が1つのみの場合
else節が1つしかなく、式が単純な場合は
条件 ? 式1 : 式2
がつかえる。
event_name = 'エイト' # if else end if event_name == 'クォドルプル' puts "スカル種目です。" else puts "スイープ種目です。" end # 条件 ? 式1 : 式2 # 条件が偽の場合は : 以降の式が実行される。 event_name == 'クォドルプル' ? puts("スカル種目です。") : puts("スイープ種目です。")
ちなみに上の場合puts "スカル種目です。"
と書くとエラーになる。
エラーの例
event_name = 'エイト' event_name == 'クォドルプル' ? puts "スカル種目です。" : puts "スイープ種目です。" # syntax errorになる
puts
の引数を()
で囲むか、puts式全体を()
で囲む必要がある。
event_name = 'エイト' event_name == 'クォドルプル' ? (puts "スカル種目です。") : (puts "スイープ種目です。") # スイープ種目です。 と表示される。
case文のwhen節を1行にまとめる
when節にthen
を明記すると1行にまとめることができる。
thenなし、改行あり
event_name = 'エイト' case event_name when 'クォドルプル' puts "スカル種目です。" when 'エイト' puts "スイープ種目です。" end
thenあり、改行なし
event_name = 'エイト' case event_name when 'クォドルプル' then puts "スカル種目です。" when 'エイト' then puts "スイープ種目です。" end # thenなし、改行なしはエラーになる。
今回の動作確認環境
Ruby 2.5.1p57