あまブログ

ドキドキ......ドキドキ2択クイ〜〜〜〜〜〜〜ズ!!

【Ruby】Sinatraでメモアプリを作る(DB編)

この記事では、RubyのWebアプリケーションフレームワークであるSinatraを使って、シンプルなメモアプリを作成します。

データ保存先のDBにはPostgreSQLを使用します。

今回は、以下の記事で作成したメモアプリのデータ保存先をPostgreSQLに変更します。

amablog.tech

PostgreSQLのインストール方法は以下を参照ください。

amablog.tech

1. 実行環境

  • macOS:12.5
  • Ruby:3.1.0
  • Bundler:2.3.12
  • PostgreSQL:14.3

2. 手順

2-1. pgのインストール

RubyからPostgreSQLを使うために必要なgem、pgをインストールします。

Gemfileに以下を追加します。

+ gem "pg"
  gem "sinatra"

以下のコマンドを実行してgemをインストールします。

$ bundle install

2-2. DB接続とテーブル定義

memo.rbでpgを使えるようにします。

- require 'json'
+ require 'pg' 

memo.rbの以下の部分を削除します。

FILE_PATH = 'public/memos.json'

def get_memos(file_path)
  File.open(file_path) { |f| JSON.parse(f.read) }
end

def set_memos(file_path, memos)
  File.open(file_path, 'w') { |f| JSON.dump(memos, f) }
end

memo.rbに以下を追加します。

def conn
  @conn ||= PG.connect(dbname: 'postgres')
end

configure do
  result = conn.exec("SELECT * FROM information_schema.tables WHERE table_name = 'memos'")
  conn.exec('CREATE TABLE memos (id serial, title varchar(255), content text)') if result.values.empty?
end
  • PG.connectでDBに接続し、インスタンス変数@connに接続情報をキャッシュ
  • configurationにはアプリ起動時に一度だけ行う処理を記述
  • PostgreSQLのシステムテーブルtablesからmemosテーブルの存在を確認
  • if result.values.empty?でmemosテーブルがなければテーブルを作成

2-3. メモ一覧の表示

memo.rbに以下を追加します。

# configure do
# ~

def read_memos
  conn.exec('SELECT * FROM memos')
end

# get '/' do

get '/memos'のルーティングブロックを以下に変更します。

get '/memos' do
  @memos = read_memos
  erb :index
end

views/index.erbのメモ一覧表示部分を以下に変更します。

<ul>
  <% @memos.each do |memo| %>
    <li>
      <a href="/memos/<%= memo["id"] %>"><%= CGI.escapeHTML(memo["title"]) %></a>
    </li>
  <% end %>
</ul>

2-4. 特定のメモの表示

memo.rbに以下を追加します。

# def read_memos
# ~

def read_memo(id)
  result = conn.exec_params('SELECT * FROM memos WHERE id = $1;', [id])
  result.tuple_values(0)
end

# get '/' do

get '/memos/:id'のルーティングブロックを以下に変更します。

get '/memos/:id' do
  memo = read_memo(params[:id])
  @title = memo[1]
  @content = memo[2]
  erb :show
end

2-5. メモの作成

memo.rbに以下を追加します。

# def read_memo(id)
# ~

def post_memo(title, content)
  conn.exec_params('INSERT INTO memos(title, content) VALUES ($1, $2);', [title, content])
end

# get '/' do

post '/memos'のルーティングブロックを以下に変更します。

post '/memos' do
  title = params[:title]
  content = params[:content]
  post_memo(title, content)
  redirect '/memos'
end

2-6. メモの編集

memo.rbに以下を追加します。

# def post_memo(title, content)
# ~

def edit_memo(title, content, id)
  conn.exec_params('UPDATE memos SET title = $1, content = $2 WHERE id = $3;', [title, content, id])
end

# get '/' do

get '/memos/:id/edit'patch '/memos/:id'のルーティングブロックを以下に変更します。

get '/memos/:id/edit' do
  memo = read_memo(params[:id])
  @title = memo[1]
  @content = memo[2]
  erb :edit
end

patch '/memos/:id' do
  title = params[:title]
  content = params[:content]
  edit_memo(title, content, params[:id])
  redirect "/memos/#{params[:id]}"
end

2-7. メモの削除

memo.rbに以下を追加します。

# def edit_memo(title, content, id)
# ~

def delete_memo(id)
  conn.exec_params('DELETE FROM memos WHERE id = $1;', [id])
end

# get '/' do

delete '/memos/:id'のルーティングブロックを以下に変更します。

delete '/memos/:id' do
  delete_memo(params[:id])
  redirect '/memos'
end

以上で終了です。


【参考】