Padrino入門 1 「Blog Tutorial」編
PadrinoはRubyベースのシンプルなWAF(Web Application Framework)であるSinatraに、Rails風の機能を追加したものです。
ORMやテンプレートエンジンなどのライブラリを自由に選択してプロジェクトを生成することができ、作成したWebアプリケーションはHerokuにデプロイ可能です。
試しに使ってみたので、備忘録がてらPadrinoの使い方について公式ドキュメントをもとに紹介していきます。
Padrinoについて知る
Padrinoに関する参考ページを紹介しておきます。
- The Elegant Ruby Web Framework - Padrino Ruby Web Framework
Padrinoの公式サイトです。ここのGUIDESに沿って進めていく予定です。 - Padrino で素敵なウェブ開発を - Padrino Ruby Web Framework
Padrinoの日本語サイトです。一部のGUIDESが日本語化されています。 - RubyKaigi2011に行った+Sinatra/Padrinoについてしゃべった ≪ blog.udzura.jp
Padrinoについて紹介されているスライド。 - Rubyist Magazine - Sinatra 再入門、 Padrino / Rack / その先の何か
るびまに掲載された記事。 - Rails Hub情報局: Railsはフルコース、Sinatraはお皿、Padrinoはビュッフェ
上記るびま記事の紹介。Railsとの比較について。 - File: README - Padrino
PadrinoのAPIドキュメント。 - File: README - Documentation for sinatra (1.3.2)
SinatraのAPIドキュメント。
Blog Tutorial
「Blog Tutorial」では、ごくシンプルなブログシステムを構築します。記事の投稿、投稿者との紐付け、RSSの生成などを行い、最終的にHerokuにデプロイします。
- Guides Blog Tutorial - Padrino Ruby Web Framework
- Guides Blog Tutorial - Padrino Ruby Web Framework(日本語)
インストール
Padrinoをgemでインストールします。
> gem install padrino
Project の生成
チュートリアルではORMとしてActiveRecord、テンプレート言語として Haml、テストフレームワークとしてShoulda、JavaScript ライブラリとしてjQueryを利用します。
以下のコマンドでプロジェクトのひな形が生成されます。
> padrino generate project sample_blog -t shoulda -e haml -c sass -s jquery -d activerecord -b
> cd sample_blog
末尾の-bフラグは、bundlerで自動的にすべての依存gemをインストールすることを意味しています。(gemはプロジェクトフォルダではなくシステム側にインストールされます)
generate projecコマンドのオプションについて詳しくは--helpで確認できます。
> padrino generate project --help
生成されるファイルは以下のとおりです。
app/ :
controllers/ : ルーティングとコントローラ
helpers/ : ヘルパーメソッドの定義
stylesheets/ : スタイルシート
views/ : ビューテンプレート
views/layouts/ : ビューレイアウト
app.rb : アプリケーションコア
config/ :
apps.rb : アプリケーションのマウント
boot.rb : ブート設定
database.rb : データベース接続設定
lib/ :
sass_init.rb : SASSの設定
public/ : 画像、スタイルシート、 JavaScript などのスタティックファイル
test/ : モデルやコントローラのテスト
test.rake :
test_config.rb :
tmp/ :
.components : プロジェクト作成時に指定したコンポーネントの情報
.gitignore :
config.ru :
Gemfile : アプリに必要な gem の依存情報
Gemfile.lock :
app/app.rb に以下を追加します。
get "/" do
"Hello World!"
end
get :about, :map => '/about_us' do
render :haml, "%p This is a sample blog created to demonstrate the power of Padrino!"
end
ローカルサーバを起動し、/と/about_usにアクセスして表示を確認します。
> padrino start
Admin Dashboard のセットアップ
Padirnoには認証付きの管理画面を自動的に生成する機能があります。以下のコマンドでadminサブアプリケーションを生成します。
> padrino generate admin
管理画面で必要になるgemをインストールします。
> bundle install
以下のコマンドでデータベースを初期化します。
> padrino rake ar:create
db/sample_blog_development.db が0byteで作成されます(省略可能)
> padrino rake ar:migrate
dbにデータが書き込まれ、db/schema.rb が作成されます
> padrino rake seed
dbに db/seeds.rb で定義されたデータを取り込みます
ログイン用のメールアドレスとパスワードの入力を求められます
ローカルサーバを起動すると、http://localhost:3000/admin で管理画面にアクセスできます。
> padrino start
投稿の作成
投稿を新規作成する機能を実装するため、「post」モデルを作成します。
> padrino generate model post title:string body:text
models/post.rb とmigrateおよびtestが作成されます
マイグレーションを実行します。
> padrino rake ar:migrate
dbにpostテーブルが追加され、db/schema.rb が更新されます
次に、投稿処理を行う「posts」コントローラを作成します。
> padrino g controller posts get:index get:show
app/controllers/posts.rb ほかいくつかのファイルが生成されます
app/controllers/posts.rb に基本的なルーティング(:index と :show)を定義します。:indexは投稿一覧を表示し、:showは単一記事を表示します。
SampleBlog.controllers :posts do
get :index do
@posts = Post.all(:order => 'created_at desc')
render 'posts/index'
end
get :show, :with => :id do
@post = Post.find_by_id(params[:id])
render 'posts/show'
end
end
postsコントローラのためのビューを作成します。
app/views/posts/index.haml
- @title = "Welcome"
#posts= partial 'posts/post', :collection => @posts
app/views/posts/_post.haml
.post
.title= link_to post.title, url_for(:posts, :show, :id => post)
.date= time_ago_in_words(post.created_at || Time.now) + ' ago'
.body= simple_format(post.body)
app/views/posts/show.haml
- @title = @post.title
#show
.post
.title= @post.title
.date= time_ago_in_words(@post.created_at || Time.now) + ' ago'
.body= simple_format(@post.body)
%p= link_to 'View all posts', url_for(:posts, :index)
PadrinoのAdmin機能では、「admin_page」により任意のモデルに対するレコードの作成、編集、削除機能を自動的に追加することができます。
投稿をAdmin機能で管理するために、以下のコマンドを実行します。
> padrino g admin_page post
サーバを再起動し、http://localhost:3000/admin にアクセスすると「Posts」タブが追加されています。「Posts」タブの「New」を選択して新規投稿が可能です。
http://localhost:3000/posts にアクセスすると投稿が表示されます。
投稿にアカウントを関連付ける
Postモデルに Account を紐づけられるよう、新しいマイグレーションを追加します。
> padrino g migration AddAccountToPost account_id:integer
db/migrate/003_add_account_to_post.rb が作成されます
マイグレーションファイルを、現存する投稿すべてに対してユーザーが紐づくように改修します。db/migrate/003_add_account_to_post.rb のself.upに以下を追加します。
# and assigns a user to all existing posts
first_account = Account.first
Post.all.each { |p| p.update_attribute(:account, first_account) }
models/post.rb にバリデーションを定義します。
class Post < ActiveRecord::Base
belongs_to :account
validates_presence_of :title
validates_presence_of :body
end
マイグレーションを実行します。
> padrino rake ar:migrate
admin/controllers/posts.rb の post :create do に以下を追加します。(「@post = Post.new(params[:post])」行の下に追加)
@post.account = current_account
app/views/posts/show.haml の「.body」行の下に以下を追加します。
.details
.author Posted by #{@post.account.email}
app/views/posts/_post.haml の「.body」行の下に以下を追加します。
.details
.author Posted by #{post.account.email}
http://localhost:3000/admin からアカウントを作成して記事を投稿し、記事とアカウントが紐付いて表示されることを確認します。
Site Layout
app/views/layouts/application.haml を作成します。
!!! Strict
%html
%head
%title= [@title, "Padrino Sample Blog"].compact.join(" | ")
= stylesheet_link_tag 'reset', 'application'
= javascript_include_tag 'jquery', 'application'
= yield_content :include
%body
#header
%h1 Sample Padrino Blog
%ul.menu
%li= link_to 'Blog', url_for(:posts, :index)
%li= link_to 'About', url_for(:about)
#container
#main= yield
#sidebar
- form_tag url_for(:posts, :index), :method => 'get' do
Search for:
= text_field_tag 'query', :value => params[:query]
= submit_tag 'Search'
%p Recent Posts
%ul.bulleted
%li Item 1 - Lorem ipsum dolorum itsum estem
%li Item 2 - Lorem ipsum dolorum itsum estem
%li Item 3 - Lorem ipsum dolorum itsum estem
%p Categories
%ul.bulleted
%li Item 1 - Lorem ipsum dolorum itsum estem
%li Item 2 - Lorem ipsum dolorum itsum estem
%li Item 3 - Lorem ipsum dolorum itsum estem
%p Latest Comments
%ul.bulleted
%li Item 1 - Lorem ipsum dolorum itsum estem
%li Item 2 - Lorem ipsum dolorum itsum estem
%li Item 3 - Lorem ipsum dolorum itsum estem
#footer
Copyright (c) 2009-2010 Padrino
reset.cssをダウンロードして public/stylesheets/reset.css に、application.sassをダウンロードして app/stylesheets/application.sass に配置します。
http://localhost:3000/posts にアクセスしてレイアウトが適用されたことを確認します。
RSS Feed を生成する
app/controllers/posts.rb の「get :index do」行を以下の内容に変更します。
get :index, :provides => [:html, :rss, :atom] do
app/views/posts/index.haml の「#posts」行の前にRSSへの参照を追加します。
- content_for :include do
= feed_tag(:rss, url(:posts, :index, :format => :rss),:title => "RSS")
= feed_tag(:atom, url(:posts, :index, :format => :atom),:title => "ATOM")
app/views/posts/index.atom.builder を作成します。
xml.instruct!
xml.feed "xmlns" => "http://www.w3.org/2005/Atom" do
xml.title "Padrino Sample Blog"
xml.link "rel" => "self", "href" => url_for(:posts, :index)
xml.id url_for(:posts, :index)
xml.updated @posts.first.updated_at.strftime "%Y-%m-%dT%H:%M:%SZ" if @posts.any?
xml.author { xml.name "Padrino Team" }
@posts.each do |post|
xml.entry do
xml.title post.title
xml.link "rel" => "alternate", "href" => url_for(:posts, :show, :id => post)
xml.id url_for(:posts, :show, :id => post)
xml.updated post.updated_at.strftime "%Y-%m-%dT%H:%M:%SZ"
xml.author { xml.name post.account.email }
xml.summary post.body
end
end
end
app/views/posts/index.rss.builder を作成します。
xml.instruct!
xml.rss "version" => "2.0", "xmlns:dc" => "http://purl.org/dc/elements/1.1/" do
xml.channel do
xml.title "Padrino Blog"
xml.description "The fantastic padrino sample blog"
xml.link url_for(:posts, :index)
for post in @posts
xml.item do
xml.title post.title
xml.description post.body
xml.pubDate post.created_at.to_s(:rfc822)
xml.link url_for(:posts, :show, :id => post)
end
end
end
end
http://localhost:3000/posts にアクセスし、head内にRSSとAtomへのリンクが追加され、それぞれ正しく生成されることを確認します。
アプリケーションのデプロイ
Herokuへのデプロイでは以下が前提となります。
- Git がインストールされていること
- Heroku account がセットアップされていること
- Heroku gem がインストールされていること
Windows環境特有の問題として、Gemfile.lockのmingw32に関する記述を削除しておく必要があります。以下の行を削除し、個別のgemでも「-mingw32」となっている箇所を削除して下さい。
PLATFORMS
x86-mingw32
アプリケーションを Git リポジトリとしてセットします。
> git init
> git add .
> git commit -m "initial commit for app"
Herokuにアップロードします。ただしこのままではまだ動作しません。
> heroku create
> git push heroku master
Herokuで動作させるためにデプロイ環境ではPostgreSQLを使用するよう変更を加えます。まず、pgをGemfileの依存関係として追加します。
# Gemfile
group :production do
gem 'pg'
end
bundleでgemをインストールします。
> bundle install
config/database.rb を production 環境向けに設定します。
# config/database.rb
postgres = URI.parse(ENV['DATABASE_URL'] || '')
ActiveRecord::Base.configurations[:production] = {
:adapter => 'postgresql',
:encoding => 'utf8',
:database => postgres.path[1..-1],
:username => postgres.user,
:password => postgres.password,
:host => postgres.host
}
以下のコマンドでRakefileを作成します。
> padrino rake gen
seed.rbで、実行時にメールアドレスとパスワードをコンソール上から入力せずに済むよう直接指定します。
# db/seeds.rb
email = "xxx@xxx.xxx"
password = "xxxx"
再度Herokuにアップロードします。アップロード時に自動的にpgのgemがインストールされます。
> git add .
> git commit -m "Added Postgres support"
> git push heroku master
マイグレーションを実行します。
> heroku rake ar:migrate
> heroku rake seed
デプロイされたアプリケーションを開いて動作を確認します。
> heroku open
おわりに
次回は「Generators」編の予定です。