ローイングファンのプログラミング日記

ボート競技やプログラミングについて書きます

PostgreSQLを使ったSinatraアプリをつくる

PostgreSQLを使ったSinatraアプリをつくる。

目次


準備

ディレクトリ/ファイル構造

ディレクトリ/ファイルの構造は次のとおり。

sinatra_app
    |- Gemfile
    |- Gemfile.lock
    |- .env
    |- myapp.rb
    |- views
        |- index.erb
    |- public *静的ファイルが必要な場合は作成する
        |- CSSファイルなど
    |- vendor
        |- bundle
            |- Gemシステムファイル
    |- .bundle


必要なGemをインストールする

Gemファイルに必要なGemを記入してbundle installする。
Bundlerについては前の記事を参照。

Bundlerを使ってgemをインストールする - ローイングファンの日記



Gemfile

# frozen_string_literal: true

source "https://rubygems.org"

git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }

# gem "rails"
# 今回必要なGem
gem "sinatra"
gem "sinatra-contrib" #sinatra/reloaderに必要
gem 'activerecord'
gem 'pg' #PostgreSQLの操作に必要
gem 'dotenv'


Sinatra

Sinatraについては前回の記事を参照。

PostgreSQLの準備

データベースは前につくったtestデータベースを使う。
PostgreSQLについては前に書いた記事を参照。

Windows10にPostgreSQLをインストールする - ローイングファンの日記

macOS10にPostgreSQLをインストールする - ローイングファンの日記

PostgreSQLのデータベースをつくる - ローイングファンの日記

PostgreSQLにテーブルをつくる - ローイングファンの日記

PostgreSQLにデータを挿入する - ローイングファンの日記

Active Record

Active Record関連の過去記事。

RubyからPostgreSQLを操作する - ローイングファンの日記

Active RecordでPostgreSQLを操作する - ローイングファンの日記

ERBライブラリ

ERBはHTMLの中にRubyのコードを埋め込むときに使うライブラリ。
Sinatraに組み込まれている。
解説ページは次のとおり。

るびま
標準添付ライブラリ紹介 ERB
https://magazine.rubyist.net/articles/0017/0017-BundledLibraries.html

ERBの主な使い方
<% %>の中に書いたコードはブラウザに表示されない。
<%= %>の中に書いたコード(の結果)はブラウザに表示される。
具体的な使い方は次のコードを参照。

コードを書く

コードを書く。

myapp.rb

require 'sinatra'
require 'sinatra/reloader'
require 'active_record'
require 'dotenv/load'

class Test < ActiveRecord::Base
    establish_connection(
        adapter:  "postgresql",
        host:     "",
        username: ENV['username'],
        password: "",
        database: "test"
    )
end

get '/' do
    @tests = Test.all
    erb :index
end


テンプレートファイルはviewsというディレクトリの中につくる。
views/index.erb

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="utf-8">
    <title>レース結果</title>
</head>
<body>
    <h1>レース結果</h1>
    <ul>
        <% @tests.each do |test| %>
            <h3><%= "レースNo:#{test['raceno']} #{test['events']} #{test['groups']}" %></h3>
            <%= "<li>#{test['rank1']}着 #{test['crew_rank1']}</li>" unless test['crew_rank1'] == "" || test['crew_rank1'] == nil %>
            <%= "<li>#{test['rank2']}着 #{test['crew_rank2']}</li>" unless test['crew_rank2'] == "" || test['crew_rank2'] == nil %>
            <%= "<li>#{test['rank3']}着 #{test['crew_rank3']}</li>" unless test['crew_rank3'] == "" || test['crew_rank3'] == nil %>
            <%= "<li>#{test['rank4']}着 #{test['crew_rank4']}</li>" unless test['crew_rank4'] == "" || test['crew_rank4'] == nil %>
            <%= "<li>#{test['rank5']}着 #{test['crew_rank5']}</li>" unless test['crew_rank5'] == "" || test['crew_rank5'] == nil %>
            <%= "<li>#{test['rank6']}着 #{test['crew_rank6']}</li>" unless test['crew_rank6'] == "" || test['crew_rank6'] == nil %>
        <% end %>
    </ul>
</body>
</html>


コードの説明

myapp.rb

  • 必要なGemをrequireメソッドで呼び出す
  • testデータベースのTestクラスをつくる
    • Active Recordを使ってtestデータベースと接続する
  • getメソッドでindexページをつくる
    • アドレスはgetにつづけてクォートで囲む
      • 今回は'/'なのでTopページになる
    • Testクラスのレコードをallメソッドですべて読みこみインスタンス変数に代入する
  • テンプレートにERBを指定する
    • ページの名前はシンボルにする
      • 今回はindex


index.erb

<ul></ul>タグ内にRubyのコードを埋め込んである。
<li></li>タグのコンテンツには<%= %>を使っているので結果がブラウザに表示される。
空レーンを非表示にするため後置分のunlessで条件をつけている。

  • クルーが""もしくはnilでなければ表示する

タグを取り除いたコードは次のとおり。

@tests.each do |test|
    "レースNo:#{test['raceno']} #{test['events']} #{test['groups']}"
    "#{test['rank1']}#{test['crew_rank1']}" unless test['crew_rank1'] == "" || test['crew_rank1'] == nil
    "#{test['rank2']}#{test['crew_rank2']}" unless test['crew_rank2'] == "" || test['crew_rank2'] == nil
    "#{test['rank3']}#{test['crew_rank3']}" unless test['crew_rank3'] == "" || test['crew_rank3'] == nil
    "#{test['rank4']}#{test['crew_rank4']}" unless test['crew_rank4'] == "" || test['crew_rank4'] == nil
    "#{test['rank5']}#{test['crew_rank5']}" unless test['crew_rank5'] == "" || test['crew_rank5'] == nil
    "#{test['rank6']}#{test['crew_rank6']}" unless test['crew_rank6'] == "" || test['crew_rank6'] == nil
end


CSSファイル

CSSファイル(静的ファイル)を作る場合はpublicという名のディレクトリをつくり、その中にファイルを置く。
今回は省略する。

コードを実行する

PostgreSQLサーバを起動する。

macOS 10の場合

pg_ctl -D /usr/local/var/postgres -l logfile start


Rubyコード(Sinatraアプリ)を実行する。

bundle exec ruby myapp.rb

WEBrickが起動したらブラウザでindex(Top)ページを表示させる。

http://localhost:4567


実行結果

実行結果は次のとおり。
ブラウザ画像

f:id:rowingfan:20180603095841p:plain

WEBrickを終了するにはcontrol + C
PostgreSQLサーバーの停止はpg_ctl stop

Windows10で不具合

Windows10環境でPostgreSQLとつながらない不具合がおきた。
なので今回の動作確認はmacOS 10のみ。
対処方法がわかったらこの記事に追記予定。

今回の実行環境

macOS 10.13.4
ruby 2.5.1p57
RubyGems 2.7.7
Bundler 1.16.2
sinatra 2.0.1
sinatra-contrib 2.0.1
Active Record 5.2.0
Pg 1.0.0
dotenv 2.4.0
PostgreSQL 10.3