arveltのソフトウェア技術メモ

Arvelt's software technology memo

SIerのエンジニアがSinatraアプリを作った話

Web系で働きたいので色々勉強しています。以前は勉強用にRailsでアプリを作りました。
今度はsinatraで作ってみました。今度のテーマは「テスト」。
あとモダンな環境を色々と試してみました。sinatra+sequel+slim+bootstrap+rspec+redmine+jenkins。


できたのがこちら。
http://www7148ue.sakura.ne.jp/todolist


ソースはもちろん公開してあります。
http://github.com/arvelt/my-todo-list-with-ruby-sinatra


メモ用に使ってたチケットはこんな感じ
http://49.212.138.162/redmine/projects/todolist-ruby-sinatra/issues


あとこのへんの内容で色々勉強会とかに出没してLTとかしたいとか思うんですが、初歩的すぎるのでぐぐればいいじゃんって感じしますのでどうしたものか、、、



以下解説。


Ruby環境の構築について
開発環境としてはWindows7+Eclipse+RDT、Ver1.9.3。本番環境にVPS上のCentOS+Apache+Passenger、Rvenvで1.9.3を入れるというやり方で臨みます。え、サーバーでそのまま開発しろ? あ、はい、いずれはそういうイケメンになりたいです。sublime text がlinuxで日本語入力できるようになったら考えます(他力本願
メインのwindows端末にRubyが入れてあったので、それを生かす形にしています。あとサーバーにRbenv入れた時にユーザーごとの設定ではなく、グローバルの設定にするところで悩みました。そのへんの覚書はこれ。http://arvelt.hatenablog.com/entry/2013/02/09/211403


Sinatra入門
クラシックタイプでまず始めます。get '/' do puts "hello world!" end だけで動いたのには感動しました。
テストコード書こうとしたあたりで何やらうまくいかなくなったので、モジュールタイプに書き直しました。
公式のGetting Startedが結構わかりやすいので一読するのがおすすめ。あとConfiguring Settingsも必要になるので先にさっと眺めておくのがおすすめ。テスト書くときにはTesting Sinatra with Rack::Testを読むのがおすすめ。つまり公式ドキュメントおすすめ。あと、Sinatra bookを読むと、結構深いところまで書いてあるのでおすすめ。私にはよくわかりませんでしたけど。
Apache上で動作させたときに、なぜかENV['hoge']が取得できない現象があったりしました。そこでapachの環境変数として設定したらとれるようになりました。(http://arvelt.hatenablog.com/entry/2013/02/11/172002Apacheのユーザーはapacheさんなのでそのへんのせいなのかなぁと思いましたがよく理解できていはいません。


・Sequel入門
RailsでActiveRcordをちょろっとさわったので、違うの使おうと思ってsequelにたどり着きました。でも実際にはAR風の書き方が楽でついそっちをつかってしまいます。複雑なSQLが必要ない場面ではAR風記述は実に便利です。しかし、複雑なSQLを書くことが避けられない場合も必ずあるとおもいます。そのような時でも生SQLに対応しているのは安心です。そういう設計がそもそも悪いといかいう話はおいておきます。
気をつけるところとしては、sequelはデータの返し方が2種類あるということですね。取得したデータがハッシュ形式で返ってくるメソッドと、オブジェクトで返ってくるメソッドがあります。(http://fujitaiju.com/blog/technology/ruby/rubysequel%E3%82%92%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB%E3%81%97%E3%81%A6ruby%E3%81%A7%E4%BD%BF%E3%81%A3%E3%81%A6%E3%81%BF%E3%81%9F/)という記事を拝読したので捗りました(他力本願 ほんとうにありがとうございます。
あとSequel::Plugins::JsonSerializer をモデルに記載しておくと、model.to_jsonでjson形式に変換してくれるのでおすすめ。


Sqlite
テーブル1つなので、十分だろうと思って選択。しかしSqliteには大雑把に言うとTEXT型とINTEGERS型しかないんですね。Ruby上のTimeやDateTimeを扱おうとしてわりとハマりました。あとODBC接続してaccessとか汎用SQLクライアントとかで覗くみたいなことがうまくやれなかったので、毎回sql叩くのがめんどいです。できるはずですよねぇ。


・Slim入門
railsでerbを使ったので、違うのをさわろうと思いました。hamlは%を一々書くのがなんかいやだったのでslimを選択。かなり気持ちよくビューを書けます。
例によって公式のReadmeを見るとなんとなくわかります。インデントを間違うと動かないのは注意。あと閉じカッコがいらないのを忘れないように。主に私とか。(http://arvelt.hatenablog.com/entry/2013/02/06/232230
あとレイアウトの入れ子や、部分使い回しについても可能です。かなりすっきりするのでおすすめ。


Twitter bootstrap入門
プログラマ方面の私としてはデザインに明るくありません。そこでcssフレームワークを使用することで、色々とごまかします。これは公式のサンプルみながら、これ使いたいってのを適用していくのがとっつきやすかったです。
ここで全体のバランスとかが考慮しきれないあたりに我が身のデザインセンスの限界を感じます。


Rspec+Rack::Test入門
メインディッシュ。データの一覧を表示するテスト1つをグリーンにするまでに、1週間はかかりました。実務ではレガシーコードにしか触れたことがないので、テストコードを走らせられる設計にするというのが本当に難しい。いきなり放り込まれても戦えるように自分でよく訓練しておきたいと思います。実際そこまで戦場ではないにしても、せめて武器の使い方はしらんとね。
junitの書き方を並行して勉強しているので、1度もTestUnit使ってないのにすっとばしてRspecを選択。単純にassertを書き連ねるよりも、状態や文脈を表現できるので仕様書に近い形式でかける、・・・らしいですね?
るびまのRsepcの話(http://jp.rubyist.net/magazine/?0035-RSpecInPractice)と、Rspecっぽい書き(http://tech.recompile.net/post/21340599029/rspec)という記事が大いに参考になりました。ありがとうございました。それでSinatraアプリをテストしたいのでRack::Testを使います。当初なかなかイメージがつかめずに大変でした。色々と試行錯誤した結果は、このリクエストしたらレスポンスにはこの文言が含まれているはず、ということをコードで表現できるようになりました。・・・できてますよね?
あとRspec上でのequelsとeqの違いで一瞬ハマりかけました。ぐぐったら同一性と同値性の話と気づけたのでなんとか回避。Javaでいうequals()と==の違いのアレ。


apache+passenger上で動かす
Redmineの公式(http://blog.redmine.jp/articles/2_3/installation_centos/)が一番参考になりました。サブディレクトリへのデプロイ方法も書いてあったので私歓喜。


RedmineとJenkins
アジャイル開発といえばこれ! ですが、Redmineはtodoとしてのチケットをためることと、メモ書きとしてwikiを使うこと以外には使用しませんでした。チケットに日付入れるとガントチャートで見えるってのは実務だと重要な気がしますね。見える化。あとバックアップと復旧を試したらちゃんとできたのでよかったです。一箇所詰まったところの覚書()。リポジトリはgithubを使用したので、redmine直ではありません。Web系では実務でもGithub使っているところが多いのではないでしょうか。
テストコードを書きましたので、デプロイもJenkinsで自動化してみました。githubへコミットすると、テストコード実行後に、Jenkinsサーバー兼本番サーバー上に展開します。実務だと多分別サーバーになるんだと思いますが、とりあえず試しとしてます。github上からurlを指定するだけでできるようになったので楽でした。便利!
困ったこと。jenkinsをtomcat上のアプリとして展開したので、スクリプト実行時のユーザーがtomcatになのでbundle installに失敗してしまう。しかもリクエスト処理するときはapacheユーザーになりますし、bundleできる管理者ユーザーとtomcatユーザーとapacheユーザーが入り乱れてしまって、権限設定がごっちゃになってしましました。ここらへんはどういうふうにするのがいいんでしょうね。さらに別サーバーだったりしたら、またややこしそうです。