この記事では、RubyのWebアプリケーションフレームワークであるSinatraを使って、シンプルなメモアプリを作成します。
データ保存先のDBにはPostgreSQLを使用します。
今回は、以下の記事で作成したメモアプリのデータ保存先をPostgreSQLに変更します。
【Ruby】Sinatraでメモアプリを作る(JSONファイル編) | あまブログ
PostgreSQLのインストール方法は以下を参照ください。
【macOS】PostgreSQLの基本操作 | あまブログ
1. 実行環境
- macOS:12.5
- Ruby:3.1.0
- Bundler:2.3.12
- PostgreSQL:14.3
- sinatra:2.2.2
- webrick:1.7.0
- sinatra-contrib:2.2.2
- pg:1.4.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
- PG::Connection.exec_params
- SQL文でプレースホルダを使う場合に使用
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
以上で終了です。
【参考】