Sinatraでデータを修正、更新する(CRUDのUpdate機能)
Rubyでシステムを構築する際に、Railsだとちょっとボリュームが多いので、そんな場合は軽量フレームワークとしてSinatra(PythonのFlaskみたいなもの)というものがあります。
そして、色々と使い方を解説したページや記事もあるのですが、なぜかデータの修正、更新機能については触れていないことが多く、それではどうやって作るのかをひたすら調べ、ようやく解決したので、備忘録として置いておきます。
まずは、この記事(自分とは別人です)のように登録機能と削除機能を作ってみてください。自分の記事はそこから補足説明となります。
なぜ、データ修正機能の記事が殆どないのか?
日本語サイトでもほとんど見つからなかった上に、MVCの観点を鑑みて、全ての機能を懇切丁寧に解説しているものは皆無だったので、英語サイトも隈なく探してみたのですが、そういったサイトは見つかりませんでした(この記事を作ろうとしたきっかけです)。
その理由は明白で、SinatraはRailsとは異なりコントローラの自動生成が簡単にできない上にRailsと記述が若干異なります。その上、公式ページの解説がかなり不親切なので、実際に機能作成を行った事例が少なく、またそのような例もコントローラ部分の解説にとどまっていることが多く、テンプレート周りの記述事例がほとんどありませんでした。
また、普通にサーバ起動してからデータ更新処理を行うと、処理がもたつきます。したがってRackサーバを使って立ち上げる方が能率的なのですが、そもそもSinatraは軽量が売りでありそこまで大掛かりなものは作らないので、利用目的としては矛盾している(実用的価値が少ない)のもありそうです。このへんも踏まえて解説できたらと思います。
ツリー構造
最低限のデータ構造はこうなっています。Rackを使うので、そのためにはconfig.ruが必要となります。config.ruは自動生成されないので、適宜作成します。
- 任意のプロジェクト名
- db
sindb.db #今回使用するDB
- public
- vendor
- views
edit.erb #編集用
index.erb #リスト
config.ru #Ruckの設定ファイル
app.rb #コントローラ
Rackの設定
Rackサーバの設定はconfig.ruで行います。色々記事がありますが、最低限これだけ必要です。
require './app' #コントローラ
run Sinatra::Application
また、Rackサーバの起動コマンドは以下の通りとなります(ローカルサーバ接続)。また、rackのデフォルトポートは9292となるので、sinatraと同じように4567にしています(bashを使ってbundle execを省略した場合、rackupコマンドで起動可能)。
# bundle exec rackup -o 0.0.0.0 -p 4567
コントローラのメソッド記述
データの更新作業は以下のプロセスを経由します。
一覧画面から修正ボタンを押下 → 編集画面に遷移 → 編集画面でデータの編集
→ 編集画面から更新ボタンを押下 →更新処理 → 一覧画面に遷移
このうち、編集画面に遷移するにはgetメソッドを使用し、部分的なデータ修正を反映させるにはpatchメソッドを使用します。また、今回はレコード名がuserとなっているので、以下のディレクトリで処理が行われます。
#編集データを編集画面(edit.erb)に遷移
get '/users/:id/edit' do
@user = User.find_by_id(params[:id]) #該当IDのデータ取得
erb :edit #編集画面の呼び出し
end
#編集画面での更新処理を反映
patch '/users/:id' do
@user = User.find_by_id(params[:id]) #該当IDのデータ情報取得
@user.name = params[:name] #更新データの代入
@user.save #データ更新の反映
redirect to "/" #一覧画面へ
end
参考にしたサイト
- Sinatra Restful Routes Readme 【英語サイト】
コントローラの全容はこのようになっています。csrf対策のために任意のトークンを発行する必要があります。
require 'sinatra'
require 'active_record' #モデルからレコード取得
require 'rack/csrf' #csrf制御に不可欠
use Rack::Session::Cookie, secret: "xxxxxxxxxxxxxxxxxxxxxxxxxxx" #任意のトークン
use Rack::Csrf, rise:true
ActiveRecord::Base.establish_connection(
adapter: 'sqlite3',
database: './db/sindb.db'
)
class User < ActiveRecord::Base
validates :name, presence: true
end
get '/' do
@title = "User List"
@users = User.all #テーブルレコードの全データ取得
erb:index
end
#新規作成
post '/create' do
User.create(name: params[:name])
redirect to('/')
end
#編集
get '/users/:id/edit' do
@user = User.find_by_id(params[:id])
erb :edit
end
#編集データの更新
patch '/users/:id' do
@user = User.find_by_id(params[:id])
@user.name = params[:name]
@user.save
#redirect to
redirect to "/"
end
#削除
post '/destroy' do
User.find(params[:id]).destroy
end
テンプレートの作成
テンプレートの注意点としてはCSRF対策を行わないと403エラーに悩まされることになります(一覧、編集画面の双方で対応が必要で、相当悩まされました)。
一覧
一覧画面はそこまで難しく考える必要ないですが、actionプロパティの値に変数を埋め込む必要があります。
<body>
<h1><%= @title %></h1>
<% @users.each do |user| %>
<form method="get" action="/users/<%= user.id %>/edit">
<ul>
<li data-id="<%= user.id %>" data-token="<%= Rack::Csrf.csrf_token(env) %>">
<%= Rack::Utils.escape_html(user.name) %>
<button type="submit" >修正</button>
<button class="delete">削除</button>
</li>
</ul>
</form>
<% end %>
<form action="/create" method="post">
<%= Rack::Csrf.csrf_tag(env) %>
<input type="text" name="name">
<input type="submit" value="追加">
</form>
</body>
編集画面
編集画面は以下の通りとなります。大事なポイントはpatch処理が必要なので、メソッドをhiddenで埋め込む必要があります。
<form action="/users/<%= @user.id %>" method="post">
<%= Rack::Csrf.csrf_tag(env) %>
<input id="hidden" type="hidden" name="_method" value="patch">
<input type="text" name="name" value="<%= @user.name %>">
<button type="submit">更新</button>
</form>
実際の動き
一覧画面(更新前)
ここではshoujiというデータを編集するので、修正ボタンを押します。
編集処理
編集画面に遷移するのでshoujiをshinjiに変更します。usersディレクトリを作る必要はなく、編集画面(edit.erb)もindex.erbと同階層に作成されています。
192.168.11.xx:4567/users/5/edit?
一覧画面(更新後)
データが反映されます。
DBで確認
sqlite3で実際に確認してみましょう。sqlite3の場合は、DBファイルをそのまま呼び出します。
#sqlite3 db/sindb.db
修正前のデータです。
sqlite> select * from users;
1|hamana
2|kawaguchi
3|motosu
4|sai
5|shouji
6|saroma
7|shikotsu
8|touya
9|kussharo
10|akan
修正後のデータです。データはしっかりと入れ替わっていました。
sqlite> select * from users;
1|hamana
2|kawaguchi
3|motosu
4|sai
5|shinji
6|saroma
7|shikotsu
8|touya
9|kussharo
10|akan
sqlite>
Author And Source
この問題について(Sinatraでデータを修正、更新する(CRUDのUpdate機能)), 我々は、より多くの情報をここで見つけました https://qiita.com/BRSF/items/85c93af57926d08055fa著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .