はじめに
大勉強会のハンズオンのエピソードです。全員でエピソードに沿ってハンズオンを行います。マシンは各自持参したマシンかイベントで用意したマシンを1名1台使用します。
シナリオ
背景
私は、社員10名の会社に勤める総務課の社員です。コンピュータが得意な為、コンピュータの購入や社員への配布にも携わっています。日頃から他の社員にコンピュータの使い方やトラブルシューティングの相談なども受けています。最近は、コンピュータサポートは私の業務の一部となってきました。
私がコンピュータが得意な理由の一つに、以前から、趣味のWebサイトをレンタルサーバで運用しています。その中で、参考書を見ながらではありますが、HTMLやCSSを書いて見栄えの良いWebページを作成したり、苦労しましたが、MySQLとPHPを使って、データベースの情報をWebページに反映させたりもしています。
弊社は、請求書と決算書の為に経理システムを導入しています。その他の業務は、それぞれの部署がExcelやWordを使って書類を作成しています。社長は日頃から、経理システム以外の業務もシステム化したいと考えていますが、費用の問題があり、外注できない状況にあります。業務は紙ベースですすめているので、どこからシステム化をすれば良いかもわからない状態です。
ある日、外回り営業マンの同僚が、交通費など、1日に使った『経費メモ』をとっていることを知りました。そのメモから経理に提出する『支払伝票』を作成しているそうです。使った当日に経費精算できる場合もあれば、数日たまる場合もあり、メモを無くしたり、いくら経費を精算したかわからなく場合もあるそうです。メモをExcelの表にしたこともありますが、手間が増えるでやめたと言っていました。そこで同僚は簡単にメモを残して、どこまで精算したかをシステム化できないか相談されました。
動機付け
この同僚の希望であれば、MySQL、HTML、PHPを使えば、Webベースの『経費メモ』のシステムをわたしのスキルでも作成できそうです。ただ、PHPを使ってスクラッチから開発するには、たとえ小さなシステムでもわたしにとっては大変です。開発を簡単にする為にWebアプリケーション開発フレームワークを使ってみようと思いました。
Webアプリケーション開発フレームワークには、『CakePHP』、『CodeIgniter』、『Ruby on Rails』などメジャーなものがありますが、学習コストが高そうです。そこで、最近知った『INTER-Mediator』というWebアプリケーション開発フレームワークを使ってみようと思いました。このフレームワークの大きな特徴の一つに、データベースをデータを『html』と『定義ファイル』を書くだけで、データの『追加, 更新, 削除』がWebページから簡単にできるようです。
初めて、Webアプリケーション開発フレームワークを使った開発に取り組むっていうのも楽しそうなので、同僚にも感謝されそうだし、いっちょやってみようと考えてみました。
課題
あなたは、この総務課の社員役となります。『INTER-Mediator』で『経費メモ』Webアプリを作りながら仕組みや開発方法をハンズオンで体験します。課題をこなすことで、『経費メモ』Webアプリを完成していきます。ゴールはこの同僚が気に入って使ってくれることです。
課題0: バーチャルマシンの用意
一般的に、Webアプリケーション開発フレームワークを使用するには、そのフレームワークを始め、データベース、Webサーバ、開発言語のインストールとセットアップ、が必要になります。『INTER-Mediator』では、開発の体験を簡単にできるよう、すべてがセットアップされたバーチャルマシンが用意されています。まずは、バーチャルマシンを用意しよう。
課題1: Webアプリのモックの作成
同僚との打ち合わせをする為、メモをもとにHTMLで一覧表画面のWebアプリのモックを作りましょう。HTMLを一部用意したので、そちらをコピーしてから作成してください。
手順1: 『page01.htmlを編集する』をクリックし、次のHTMLを<body>タグの間にコピーする。
<table>
<thead>
<tr>
<th>日付</th>
<th>借方科目</th>
<th>貸方科目</th>
</tr>
</thead>
<tbody>
<tr>
<td>2018-05-17</td>
<td>旅費交通費</td>
<td>現金</td>
</tr>
</tbody>
</table>
手順2: 『page01.htmlを表示する』をクリックし、ページを確認する。
解答例: うまくいかなった方はこちらこコピーしてください。
<table>
<thead>
<tr>
<th>日付</th>
<th>借方科目</th>
<th>貸方科目</th>
<th>相手先</th>
<th>摘要</th>
<th>出金</th>
<th>起票</th>
</tr>
</thead>
<tbody>
<tr>
<td>2018-05-17</td>
<td>旅費交通費</td>
<td>現金</td>
<td>公共交通機関</td>
<td>新小岩<->新宿 @302x2</td>
<td>604</td>
<td><input type="checkbox" name="issued" value="1" checked / ></td>
</tr>
<tr>
<td>2018-05-17</td>
<td>通信費</td>
<td>現金</td>
<td>葛飾郵便局</td>
<td>レターパックライト</td>
<td>360</td>
<td><input type="checkbox" name="issued" value="1" checked / ></td>
</tr>
<tr>
<td>2018-05-17</td>
<td>旅費交通費</td>
<td>現金</td>
<td>公共交通機関</td>
<td>四ツ木<->浅草 @328x2</td>
<td>656</td>
<td><input type="checkbox" name="issued" value="1" checked / ></td>
</tr>
</tbody>
</table>
課題2: MySQLのスキーマを作成
同僚にWebページを見せたら、『この感じで、データが入力できれば、、、』という話なりました。つぎに、データベース作成に入ります。それぞれの経費を1レコードするテーブルを考えてMySQLのスキーマを作ります。
タグ内の要素が、MySQLでのテーブル定義となります。また
タグ内の要素がレコードとなります。手順1: テーブル名を決める。
『経費のメモ』というアプリのテーブルなので、『expenses_memo』にします。
手順2: テキストエディタを使って、HTMLのテーブルをカンマ切りテキスト化する。
日付,借方科目,貸方科目,相手先,摘要,出金,起票
2018-05-17,旅費交通費,現金,公共交通機関,新小岩<->新宿 @302x2,604,√
2018-05-17,通信費,現金,葛飾郵便局,レターバックライト,360,√
2018-05-17,旅費交通費,現金,公共交通機関,四ツ木<->浅草 @302x2,656,√
手順3: ヘッダデータ部分を英単語にする。
日付,借方科目,貸方科目,相手先,摘要,出金,起票
date,debit,credit,destination,summary,withdraw,issued
手順4: PRIMARY KEYとして一意なデータを入れるid列を追加する。
id,date,debit,credit,destination,summary,withdraw,issued
1,2018-05-17,旅費交通費,現金,公共交通機関,新小岩<->新宿 @302x2,604,√
2,2018-05-17,通信費,現金,葛飾郵便局,レターバックライト,360,√
3,2018-05-17,旅費交通費,現金,公共交通機関,四ツ木<->浅草 @302x2,656,√
手順5: ヘッダとデータを分離する
id,date,debit,credit,destination,summary,withdraw,issued
1,2018-05-17,旅費交通費,現金,公共交通機関,新小岩<->新宿 @302x2,604,√
2,2018-05-17,通信費,現金,葛飾郵便局,レターバックライト,360,√
3,2018-05-17,旅費交通費,現金,公共交通機関,四ツ木<->浅草 @302x2,656,√
手順6: ヘッダをカンマで改行する。(issuedのあとにもカンマを入れる)
id,
date,
debit,
credit,
destination,
summary,
withdraw,
issued,
手順7: ヘッダ(列名)あとに半角スペースを入れて、列のデータ型を入力する。
id INT(11),
date DATE,
debit VARCHAR(10),
credit VARCHAR(10) ,
destination VARCHAR(20),
summary VARCHAR(20) ,
withdraw NUMERIC(8,0),
issued CHAR(1),
手順8: idにNOT NULLとAUTO_INCREMENTを追加してPRIMARYキーにする。
id INT(11) NOT NULL AUTO_INCREMENT,
date DATE,
debit VARCHAR(10),
credit VARCHAR(10) ,
destination VARCHAR(20),
summary VARCHAR(20) ,
withdraw NUMERIC(8,0),
issued CHAR(1),
PRIMARY KEY (id)
手順9: ここまで列の定義ができたので、create文を追加してSQLにする。
CREATE TABLE expenses_memo (
id INT(11) NOT NULL AUTO_INCREMENT,
date DATE,
debit VARCHAR(10),
credit VARCHAR(10) ,
destination VARCHAR(20),
summary VARCHAR(20) ,
withdraw NUMERIC(8,0),
issued CHAR(1),
PRIMARY KEY (id)
);
手順10: INSERT文でデータを追加する。(id列は、AUTO INCREMENTなので、挿入しなくてもナンバリングされる。)
INSERT INTO expenses_memo(date,debit,credit,destination,summary,withdraw,issued) VALUES ('2018-05-17','旅費交通費','現金','公共交通機関','新小岩<->新宿 @302x2',604,'1');
INSERT INTO expenses_memo(date,debit,credit,destination,summary,withdraw,issued) VALUES ('2018-05-17','通信費','現金','葛飾郵便局','レターバックライト',360,'1');
INSERT INTO expenses_memo(date,debit,credit,destination,summary,withdraw,issued) VALUES ('2018-05-17','旅費交通費','現金','公共交通機関','四ツ木<->浅草 @302x2',656,'1');
課題3: SQL文のコマンド入力
作成したSQL文を使って、データベースにテーブルを作成します。シェルを使ってコマンドを入力します。
手順1: シェルからサーバにアクセスする。
$ ssh developer@192.168.56.101
[password]
$ mysql -u root -p test_db
[password]
手順2: tableを作成する。
CREATE TABLE expenses_memo (
id INT(11) NOT NULL AUTO_INCREMENT,
date DATE,
debit VARCHAR(10),
credit VARCHAR(10) ,
destination VARCHAR(20),
summary VARCHAR(20) ,
withdraw NUMERIC(8,0),
issued CHAR(1),
PRIMARY KEY (id)
);
describe expenses_memo;
手順3: データ追加する。
INSERT INTO expenses_memo(date,debit,credit,destination,summary,withdraw,issued) VALUES ('2018-05-17','旅費交通費','現金','公共交通機関','新小岩<->新宿 @302x2',604,'1');
INSERT INTO expenses_memo(date,debit,credit,destination,summary,withdraw,issued) VALUES ('2018-05-17','通信費','現金','葛飾郵便局','レターバックライト',360,'1');
INSERT INTO expenses_memo(date,debit,credit,destination,summary,withdraw,issued) VALUES ('2018-05-17','旅費交通費','現金','公共交通機関','四ツ木<->浅草 @302x2',656,'1');
select * from expenses_memo;
課題4: INTER-Mediatorを使ってWebアプリを作成
ここまで、データベースの準備ができました。INTER-Mediatorフレームワークを使って、データベースと連動するWebアプリを作成します。
INTER-Mediatorフレームワークは、データベース、定義ファイル、ページファイルが必要です。定義ファイルとは、PHPで記述したKEYとVALUEをセットにした設定ファイルです。ページファイルは、HTML5で記述します。タグの属性にINTER-Mediator特有の設定を行うことで、データベースの情報を表示させられます。
はじめてINTER-Mediator体験される方は、解説ムービーをみましょう。
INTER-Mediatorの概要https://t.co/wbEDkH5wxe
— motofumi iijima (@motofumii) 2018年7月12日
手順1:定義ファイル(def02.php)を作成する。
name: expenses_memo
key: id
db-class: PDO
dsn: mysql:host=localhost;dbname=test_db;charset=utf8
user: web
password: password
Debug: false
手順2:page01.htmlをpage02.htmlへコピーし、定義ファイルを変更する。
編集前: <script type="text/javascript" src="def01.php"></script>
編集後: <script type="text/javascript" src="def02.php"></script>
手順3:htmlを編集する
- 繰り返しは1つにする
- <input>にすると編集可能
- data-imで関連付け
編集前: <td>2018-05-17</td>
編集後: <td><input type="text" data-im="expenses_memo@date"/></td>
<tbody>
<tr>
<td><input type="text" data-im="expenses_memo@date"/></td>
<td><input type="text" data-im="expenses_memo@debit"/></td>
<td><input type="text" data-im="expenses_memo@credit"/></td>
<td><input type="text" data-im="expenses_memo@destination"/></td>
<td><input type="text" data-im="expenses_memo@summary"/></td>
<td><input type="text" data-im="expenses_memo@withdraw"/></td>
<td><input type="checkbox" data-im="expenses_memo@issued" value="1"/></td>
</tr>
</tbody>
課題5:追加(insert)、削除(delete)を追加する。ナビゲーションも追加する。
手順1:定義ファイル(def02.php)を編集する。
repeat-control: confirm-insert confirm-delete
手順2:HTMLファイル(page02.html)を編集して、tableに列を追加する。
<table>
<thead>
<tr>
<th>日付</th>
<th>借方科目</th>
<th>貸方科目</th>
<th>相手先</th>
<th>摘要</th>
<th>出金</th>
<th>起票</th>
<th></th>
</tr>
</thead>
<tbody>
<tr>
<td><input type="text" data-im="expenses_memo@date"/></td>
<td><input type="text" data-im="expenses_memo@debit"/></td>
<td><input type="text" data-im="expenses_memo@credit"/></td>
<td><input type="text" data-im="expenses_memo@destination"/></td>
<td><input type="text" data-im="expenses_memo@summary"/></td>
<td><input type="text" data-im="expenses_memo@withdraw"/></td>
<td><input type="checkbox" data-im="expenses_memo@issued" value="1"/></td>
<td></td>
</tr>
</tbody>
</table>
手順3:ナビゲーションを追加する為、定義ファイル(def02.php)を編集する。
paging: true
records: 10
maxrecords: 100
手順4:ナビゲーションを追加する為、HTMLファイル(page02.html)の<body>直下に次を追加する。
<body>
<div id="IM_NAVIGATOR"></div>