以前作ったSinatraアプリをPadrinoで書き直した

ももクロの人気上昇ぶりをグラフで可視化する - すぎゃーんメモ
という記事で作ったアプリをちょっと作り直した。

というかんじでシンプルなSinatraアプリでpgから直接SQLを叩いて云々してhamlレンダリング、というかたちだったものを、

を使った構成に。
あとはTwitter bootstrapHighstockのアップデートなど。

Padrinoメモ

gemでPadrinoをインストールしてpadrino gen project hogeみたいなかんじでスケルトン作成。ORMやtemplate engineは色々選べるのでオプションで指定。Herokuで動かすの想定しているなら-a postgresとか。
padrino startでアプリを起動できる。
モデルやコントローラを追加するときは

$ padrino gen model fuga
$ padrino gen controller piyo

とかで作ると自動でテストやヘルパーやmigration用スクリプトなども追加してくれるっぽい。便利。

Padrino app on Heroku

Herokuで動かすために諸々設定。
Procfileには

web: bundle exec padrino start -a thin -p $PORT

とか記述しておく(Gemfileにthin追加しておく)。


データベースはORMがSequelの場合、config/database.rb

Sequel::Model.db = case Padrino.env
  when :production  then Sequel.connect(ENV['DATABASE_URL'], :loggers => [logger])
end

とか書いておけば繋がるはず。migrationは

$ padrino rake sq:migrate:*

とかでゴニョゴニョできるっぽい。deploy後に本番の方を更新する場合は

$ heroku run padrino rake sq:migrate:auto

とかでいいのかな。

Before After

Heroku Scheduler

コメント数の情報を更新するのに、以前は
https://github.com/sugyan/momoclo-visualizer/blob/ff93c6459933433a441c4349a78c80701acb6877/bin/scrape.rb
というスクリプトを用意して実行させていたけど、今はrake taskとして
https://github.com/sugyan/momoclo-visualizer/blob/143698ccba5d2128da686bf42940cb1cbe91ae18/tasks/scrape.rake
というのを定義して、$ padrino rake scrapeで実行するようにした。
DBの接続とか意識せずに書けるしmodelに突っ込むだけなので簡潔になった。

JSON API

Highchartsで使うコメント数の情報は、SQLで引いた結果をJSON APIで返してAJAXで使う、というかんじなのだけど、
https://github.com/sugyan/momoclo-visualizer/blob/ff93c6459933433a441c4349a78c80701acb6877/app.rb#L28
と、アレげだったものが

Visualizer.controllers :api do
  get :blog_comments, :provides => :json, :cache => true do
    expires_in 60
    Entry.for_highstock.to_json
  end
end

と、非常に簡潔に書けるようになった。モデルの方で

class Entry < Sequel::Model
  unrestrict_primary_key
  dataset_module do
    def for_highstock
      # ...
    end
  end
end

と、どんな情報を返すかだけ定義してるだけ。コントローラの方では「JSONで返す」「結果は60秒キャッシュする」といったことを簡単に指定できるので便利。

use Memcache

キャッシュにはDalliを使って、app/app.rb

  register Padrino::Cache
  enable :caching
  set :cache, Padrino::Cache::Store::Memcache.new(
    ::Dalli::Client.new(
      ENV['MEMCACHE_SERVERS'] || '127.0.0.1:11211',
      :exception_retry_limit => 1,
      :username => ENV['MEMCACHE_USERNAME'],
      :password => ENV['MEMCACHE_PASSWORD'],
  ))

と書いておけばだいたいどこでも使えるはず。

from Haml to Slim

まぁ書き方のクセはあるものの、慣れればどちらも大して変わらないかな?ライトに使う分には。
パフォーマンス的な部分は比較していないし分からない。

まとめ

まぁ、単純にPadrinoに興味があって使ってみたかったので使ってみた、というわけですが。
今回はほぼ1ページだけの簡単なアプリだったのでそれほど恩恵を受けなかったけど、ページ数が多くなったり複雑なことが増えてくるとSinatraだとキツくなってくる部分があると思っていて、Padrinoならそのへんうまくキレイに書けるようになるのでは?と思いました。
あとテストとかも書きやすそうな気がする。