Padrino で Hello world!

こんにちは。麺処まつば副店長です。
1ヶ月以上ぶりの更新です。…いやちょっと本業が少々立て込んでおりまして…
決して決してゼルダとかゼルダとかゼルダで遊んでたわけじゃないですよ?

さてさて、副店長、これまで sinatra を愛用していたのですが、
ちょっと前に padrino のお勉強会なぞ参加いたしまして、こりゃ便利そうだなってことで
少々いじってみました。
#万が一、他の記事の続き早く書けというお叱りがあるようでしたら
#ご意見ポストへお願い致します(深々)
#いくつかあるのは認識しています…(店長の目がコワイ)

まず、padrino って何?ってお客様はコチラへどうぞ
http://jp.padrinorb.com/

僭越ながら、副店長なりに噛み砕いて申し上げますと…
sinatra って DB や view を使いたかったらライブラリなり何なり自分で入れる必要があるのですが、
padrino ではそれらが最初から色々用意されています。
sinatra には無い便利な機能が色々ついていて rails に近いけど、
そこまで大げさじゃなくていいんだけど…でも楽したい…といったとき便利かと思います(笑)

それでは、一番最初なのでまずは恒例の「Hello world!」をやってみたいと思います。
…が、「趣味は変なものづくり」と公言している副店長としては
普通の「Hello World!」をつくるわけにはいかないので
Hello World!」風味のちょっと変なこんなものを作ります。

画面を表示して……

「はろーわ…」をクリックすると………

ややツンデレめいたセリフと、肩透かし食らった回数を表示。

うわーホントしょうもないですねー。
でもやります(笑)


手順はこんなカンジです。
1. インストール
2. プロジェクトの作成
3. DBの設定
4. model + migrate
5. controller
6. view
7. javascript
8. 実行

では作っていこうと思います。

インストール

まずはインストールしないと何もできないのでコチラを一発叩きます。

$ gem install padrino

コマンド一発で何やら沢山入ります。

プロジェクトの作成

インストールができたら、次はプロジェクトを作ります。
padrino では、プロジェクトを生成するためのコマンドも用意されてます。
プロジェクト生成時に、使うライブラリ等の指定も出来ます。
今回は shoulda、haml、sass、jqueryActiveRecordmysqlを指定してみます。
最後の「-b」オプションは、必要なgemを勝手に入れてくれるという魔法の呪文だそうです。

$ padrino g project pad_hw -t shoulda -e haml -c sass -s jquery -d activerecord -a mysql -b
$ cd pad_hw

プロジェクト「pad_hw」が出来ました。できたプロジェクトの中を覗いてみると、
app/controller や config、publicといったおなじみのディレクトリが並んでいます。

DBの設定

折角なのでDBも使ってみます。データベース接続の設定は「config/database.rb」
プロジェクト作成時にmysqlを指定したので、もう既にmysql仕様になっていました。
DB名と接続ユーザを変更して保存します。(とりあえず development だけ)

config/database.rb

(略)
 16 ActiveRecord::Base.configurations[:development] = {
 17   :adapter   => 'mysql',
 18   :encoding  => 'utf8',
 19   :reconnect => true,
 20   :database  => "pad_hw",
 21   :pool      => 5,
 22   :username  => 'pad_hw',
 23   :password  => 'pad_hw',
 24   :host      => 'localhost',
 25   #:socket    => '/tmp/mysql.sock'
 26 
 27 }
(略)

当然、DBも用意しておきます。

mysql> create database pad_hw default character set utf8;

model + migrate

続いて、モデルなど作ってみます。今回はカウントアップのデータしか持たないので、
簡単にこんなカンジのこざっぱりとしたテーブルを使ってみます。

カラム名 デフォルト
id integer NULL
cnt integer 0
created_at datetime NULL
updated_at datetime NULL

モデルをサクッと作っちゃいます。

$ padrino g model counter cnt:integer
apply orms/activerecord
apply tests/shoulda
create models/counter.rb
create test/models/counter_test.rb
create db/migrate/001_create_counters.rb

で、counter テーブルにタイムスタンプを追加します
db/migrate/001_create_counters.rb

  1 class CreateCounters < ActiveRecord::Migration
  2   def self.up
  3     create_table :counters do |t|
  4       t.integer :cnt, :default => 0
  5       t.timestamps
  6     end
  7   end
  8 
  9   def self.down
 10     drop_table :counters
 11   end
 12 end

そしたら migrate を走らせます。

$ padrino rake ar:migrate

DBを確認して、countersテーブルができていることを確認します。

mysql> desc counters;

Field Type Null Key Default Extra
id int(11) NO PRI NULL auto_increment
cnt int(11) YES 0
created_at datetime YES NULL
updated_at datetime YES NULL

controller

続いてコントローラを作成します。
とりあえず、index(get) と カウントアップ用の countup(post) の2つのメソッドをおいておきます。

$ padrino g controller counters get:index post:countup
create app/controllers/counters.rb
create app/helpers/counters_helper.rb
create app/views/counters
apply tests/shoulda
create test/app/controllers/counters_controller_test.rb

できたコントローラに手を加えます。
app/controllers/counters.rb

  1 # encoding: utf-8
  2 
  3 PadHw.controllers :counters do
  4   get :index do
  5     render 'counters/index'
  6   end
  7 
  8   post :countup do
  9     # カウントアップ
 10     c = Counter.find_or_create_by_id(1)
 11     c.cnt = (c.cnt || 0) + 1
 12     c.save
 13     return c.cnt.to_s
 14   end
 15 
 16 end

4〜6行目の index は、とりあえずページを表示するだけ、
8〜14行目の countup は、上で作ったcountersテーブルから
IDが「1」のレコードを引っ張り出してきてカウントアップして保存。
そしてカウントアップの結果を返す、という post のみ受けつけるメソッドです。( ajax で使います)

view

そして見た目に入ります。
今回は、プロジェクト作成時に宣言したハムちゃんを使います。

app/views/counters/index.haml

  1 -# encoding:utf-8
  2 !!!XML
  3 !!!
  4 
  5 %html{:lang => "ja"}
  6   %head
  7     %meta{:content=>"text/html", :charset=>"utf-8"}
  8     %title Hello World ...?
  9     %script{:type => 'text/javascript', :src => "/javascripts/jquery.js"}
 10     %script{:type => 'text/javascript', :src => "/javascripts/countup.js"}
 11   %body
 12     %div#str1
 13       %a{:href => "#", :id => "countup"} はろーわ…
 14     %div#str2

1行目は、urf-8を使います、という宣言。
コレがないと、こんなエラーが出てしまいます……

Encoding::UndefinedConversionError at /counters/
"\xE3" from ASCII-8BIT to UTF-8

9〜10行目で使う javascript のファイルを呼出し。
13行目で、javascript を呼び出すためのリンク「はろーわ…」を置いています。

本来、layout を使うものだと思うんですが
今回は Hello world で、ページ1枚しかないので使ってません。
本気の変なものつくるときには使います…。

javascript

折角なので、jquery 使ってみます。
jquery.jsはプロジェクト作成時に指定したので勝手に入ります。便利)
public/javascripts/countup.js

  1 $(function(){
  2   $("#countup").click(function() {
  3     new $.ajax({
  4       type: "POST",
  5       url: "/counters/countup",
  6       success: function(cnt){
  7                  $("#str1").text("「…ーく」とかいって。「…るど」とか言わないんだからねっっ");
  8                  $("#str2").html("<br /><br />肩透かしを食らった人ココまで " + cnt + " 人")
  9                },
 10       error: function(){alert("error");}
 11     });
 12   });
 13 });
 14 

上で作った view の「はろーわ…」のリンクをクリックするとajax でリクエストを送信します。
すると、サーバ側で counters テーブルの値を1つカウントアップ。その結果を返してきます。
javascript では、「…ーく」とかいって。「…るど」とか言わないんだからねっっ
という言葉とともに、今まで肩透かしをくらった回数を結果として表示します。

うーん我ながら実にしょうもないですね(笑)

実行

バンドルして実行です。

$ bundle install
$ padrino start

特にポート指定してないので、これでつなげます。
http://localhost:3000/

実際にリンクをポチッとしてみましょう………。

あぁぁ……しょうもない…しょうもなさすぎます…。
こんな便利なフレームワーク使って、こんなしょうもないものを…。
コレに懲りず、今後ももっとしょうもないものをつくろうと思います。

<TODO>
padrino コマンドは色々あるようなので後日(気が向いたら)まとめてみようと思います。