新しいフレームワークについての文章を読むときに、私はしばしば、フレームワークについて詳しくなるには、短い、簡単なアプリケーションを開発する内容のチュートリアルを読むことが一番だと思います。そういったチュートリアルは、新しいユーザに対して、フレームワークを利用した際の開発の流れやプロセスについての「感覚」をスピーディに身につけさせてくれます。このガイドでは、ユーザに単純なブログを Padrino でどう開発するかを示します。チュートリアルに沿って、各ステップごとに説明を付与し、また関連するより詳細な情報へのリンクも提供しています。
Screencast
このチュートリアルの内容を収めたチュートリアルも利用できます:
- blip.tv で見る (Select fullscreen)
- Vimeo で見る (Low Resolution)
- ファイルダウンロード (211 Mb, 12:00 in Quicktime)
PeepCode にて人気投票中ですので、ぜひ新しい Padrino の Screencast を 投票 してください!
Study Guide
このチュートリアルをスキップしたり、すぐに完成したブログを見たい際は、 blog tutorial repository をチェックアウトすることができます(Git が必要です)。
$ git clone git://github.com/padrino/sample_blog.gitもしくは、 blog tutorial project template を実行すれば、ブログプロジェクトをステップごとに、我々の自慢のテンプレート生成プログラムを用いつつ作成してくれます。単に、以下を実行するだけです:
$ padrino g project sample_blog --template sampleblogテンプレートジェネレータについての詳細は、 ジェネレータガイド を参考にしてください。
インストール
Padrino アプリケーションの開発のためには、いくつかのものをインストールしなければなりません。まず第一に、我々はもちろん、 ruby と rubygems をインストールしなければならないでしょう。そうしたら、 Padrino フレームワークの gem をインストールできます:
$ sudo gem install padrinoインストールに関する詳細は、 installation guide で確認できます。これらがすべて完了すれば、すべての必要な依存ライブラリは準備済みになり、サンプルブログアプリの開発に取りかかれるでしょう。
Project の生成
Padrino のアプリケーションを作成するには、便利な Padrino ジェネレータを利用するのがよいやり方でしょう。 Rails に似て、 Padrino にもプロジェクトジェネレータがあり、あなたがアイデアを実現するに当たって必要なすべてのファイルを含んだアプリケーションのスケルトンを生成してくれます。 Padrino はアグノスティックなフレームワークで、様々なテンプレート、テスト、 JavaScript やデータベースに関するコンポーネントを利用できます。 generators guide を読むことで、より詳しくなれるでしょう。
このサンプルアプリケーションのために、我々は ORM として ActiveRecord を、テンプレート言語として Haml を、テストフレームワークとして Shoulda 、そして jQuery JavaScript ライブラリを利用することとしましょう。上記を念頭に、我々の新規プロジェクトを作成します:
$ padrino g project sample_blog -t shoulda -e haml -c sass -s jquery -d activerecord -bこのコマンドは基本的な Padrino プロジェクトを作成し、どんなファイルが生成されたかを綺麗にレポート出力してくれます。どういう感じかは、 こちらの gist で確認できます。なお、上記の -b フラグは、最後に bundler で自動的にすべての依存 gem をインストールすることを意味しています。いま、すべきことは、新しいプロジェクトディレクトリに cd することだけです。
$ cd sample_blog
これで、すべての必要な依存 gem をすべてインストールした上で、新しく作成されたプロジェクトのルーとディレクトリに入り込むことができます。では、開発を続ける前に、個別の重要なファイルを詳細に見てみましょう。
- Gemfile – アプリに必要な gem の依存情報がこのファイルにすべて含まれているか確認してください!
- app/app.rb – これは、あなたのアプリケーションコアで、一番最初に優先されるべきファイルです。
- config/apps.rb – これは、どのアプリケーションがどこにマウントされるかを定義します。
- config/database.rb – このファイルは、あなたの選んだデータベースアダプタについて、接続情報の詳細を定義します。
以下の、重要なディレクトリも同様に生成されます:
- app/controllers – ここには、 Padrino のルーティングとコントローラを格納します。
- app/helpers – ここには、ヘルパーメソッドの定義ファイルが格納されます。
- app/views – ここには、コントローラ内で利用されるべきビューテンプレートが入ります。
- lib – ここには、あなたのプロジェクトで利用する予定のある拡張、ライブラリその他を入れることが出来ます。
- public – ここには、画像、スタイルシート、 JavaScript などのスタティックファイルが配置されます。
- test – ここは、モデルやコントローラのテストを配置する場所です。
さて、まずは config/database.rb ファイルについて説明します。データベース接続設定を正しくしましょう。チュートリアルでは、ここまでは、デフォルトの設定が「問題の無い」ものでしたが、 SQLite3 のデータベースが db/sample_blog_development.db 内に保存されるようにしましょう。
同時に、いくつかの簡単なルーティングを設定して、 Padrino のルーティングの仕組みのデモをさせてください。 app/app.rb を開いて、以下のルーティングを追加します:
# app/app.rb class SampleBlog < Padrino::Application register Padrino::Rendering register Padrino::Helpers # Add these routes below to the app file... 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 end
最初のルーティングは、 root URL をあらわす普通の文字列です。二番目のルーティングは、一行の「about」ページを定義する、インライン Haml テンプレートを利用したもので、ぴったり ‘/about_us’ にマッピングされます。 Symbol :about は、のちほどルーティングを参照する際に使います。
複雑なルーティングシステムを理解するために、是非 controllers guide をご覧ください。
Admin Dashboard のセットアップ
このプロジェクトのデータを閲覧、検索、編集するための Padrino の管理画面をセットアップするのにいいタイミングでしょう。コンソールに戻って、以下をタイプします:
sample_blog $ padrino g admin sample_blog $ bundle install
これで、プロジェクトに管理用のサブアプリケーションが作成され、 config/apps.rb でマウントされます。このコマンドの出力は この gist で確認できます。
ここで、我々は以下の手順にしたがいデータベースを作成し、マイグレーションを動かし、 db/seeds.rb に作成されたデータを取り込むための seed タスクを走らせる必要があるでしょう。ターミナルで以下を打ち込みます:
sample_blog $ padrino rake ar:create sample_blog $ padrino rake ar:migrate sample_blog $ padrino rake seed
このプロセスの間に、あなたは管理画面にログインするための email とパスワードを入力する必要が出てくるでしょう。この組み合わせは、後ほど開発で利用しますので覚えておいてください。
管理画面についてのより詳しい機能は、 Admin Panel Guide をチェックしてみてください。
Booting Padrino
いま、 Padrino のプロジェクトは生成され、データベースの設定も管理画面の作成も終わりましたので、 Padrino のアプリケーションサーバを立ち上げることができます。これは、 Padrino の組込タスクで簡単に実行できます。単に以下をターミナルで実行するだけです:
sample_blog $ padrino startあなたは、一つもエラーを見ないことでしょう。そしてターミナルは以下のような出力をするでしょう:
=> Located unlocked Gemfile for development => Padrino/0.10.5 has taken the stage development on port 3000 >> Thin web server (v1.2.7 codename This Is Not A Web Server) >> Maximum connections set to 1024 >> Listening on localhost:3000, CTRL+C to stop
ターミナルでのコマンドについてより詳しくは、 Development and Terminal Commands ガイドをご覧ください。
あなたのアプリケーションはいま http://localhost:3000 で見られます。この URL をブラウザで参照すると、 Hello World! が描画されているのを確認できるでしょう。これは、我々がこのチュートリアルで先ほど定義したものですね。同様に、管理画面にも以下の URL からアクセスできます:
そうして、さきほど rake seed コマンドで入力した管理者 email / パスワードでログインします。この管理エリアを探検し、存在するアカウントを確認してみましょう。ここの詳細は後ほどまた解説します。管理画面の諸機能は Admin Panel Guide をチェックしてください。
すばらしことに、 Padrino は development 環境におけるコードの自動リロード機能を完全にサポートしています。つまり、あなたは Padrino のサーバーを走らせたままにでき、なおかつコードを変更すれば、ブラウザで更新した際にその変更が反映されているということを意味します。新しいターミナルを立ち上げ、ディレクトリに cd し、サーバを走らせたままにしたくなるかもしれません。
投稿の作成
いま、アプリケーションは準備完了し、レイアウトは決まったので、我々のブログの投稿を閲覧し、さらに投稿を新規作成する機能を実装しましょう!
まず、モデルをジェネレートするところから始めましょう。
sample_blog $ padrino g model post title:string body:text => Located unlocked Gemfile for development create models/post.rb create test/models/post_test.rb create db/migrate/002_create_posts.rb
タイムスタンプをマイグレーションファイルに追加しましょう。
# db/migrate/002_create_posts.rb class CreatePosts < ActiveRecord::Migration def self.up create_table :posts do |t| t.string :title t.text :body t.timestamps end end def self.down drop_table :posts end end
つづいて、マイグレーションを実行します。
sample_blog $ padrino rake ar:migrate => Executing Rake ar:migrate ... == CreatePosts: migrating ==================================================== -- create_table("posts", {}) == CreatePosts: migrated (0.0016s) ===========================================
これで、 “post” モデルが作成されました。つづいて、コントローラを作成し、基本的な閲覧機能を作ります。
sample_blog $ padrino g controller posts get:index get:show => Located unlocked Gemfile for development create app/controllers/posts.rb create app/helpers/posts_helper.rb create app/views/posts create test/controllers/posts_controller_test.rb
いくつかの基本的なルーティング (:index と :show) をコントローラに加えましょう。
# app/controllers/posts.rb 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
これは、 Rails で実装するそれによく似ています。
次に、これらのコントローラのためのビューを作りたいです。
# 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 機能はレコードの作成、編集、削除機能を自動的に作ってくれます。投稿を Padrino Admin で管理するには、以下のコマンドを走らせます。
sample_blog $ padrino g admin_page post => Located unlocked Gemfile for development create admin/controllers/posts.rb create admin/views/posts/_form.haml create admin/views/posts/edit.haml create admin/views/posts/index.haml create admin/views/posts/new.haml inject admin/app.rb
サーバーを再起動して。試しに走らせてみましょう。
http://localhost:3000/admin にアクセスし、先ほどの認証情報でまたログインしてください。
いま、2つのタブが存在するはずです。一つは Posts のため、もう一つはアカウントのためです。Postsをクリックします。
Padrino Admin では “New” をクリックすることで簡単に新規レコードを作成できます。その画面では、先ほど作成した投稿モデルにセットしたフィールドがすべて入力できるフォームが存在するはずです。
注意: padrino g admin_page は、モデルとマイグレーションを作成した あとで 実施してください。
ここで、あなたはいくつかの投稿を管理画面経由で追加したわけですが、 http://localhost:3000/posts を見てみて、あなたの作成した投稿が “index” アクションで見られるかどうかを確認してみましょう!
また、すべてのルーティングを padrino rake routes コマンドで見ることもできます:
$ padrino rake routes
URL REQUEST PATH
(:about) GET /about_us
(:posts, :index) GET /posts
(:posts, :show) GET /posts/show/:idこれは、コントローラと URL の対応付けを理解する上で役に立つと思います。
投稿にアカウントを関連付ける
ここまでで、実は各投稿は「投稿したユーザー」に紐づいていない状態です。ここで、 Post モデルを再び見てみましょう。 Post に Account を紐づけられるよう、新しいマイグレーションを追加します。
sample_blog $ padrino g migration AddAccountToPost account_id:integer => Located unlocked Gemfile for development create db/migrate/003_add_account_to_post.rb
これで、必要な account_id フィールドが投稿に追加されるマイグレートが作成されます。
では、マイグレーションファイルを、現存する投稿すべてに対してユーザーが紐づくように改修しましょう。
# db/migrate/003_add_account_to_post.rb class AddAccountToPost < ActiveRecord::Migration def self.up change_table :posts do |t| t.integer :account_id end # and assigns a user to all existing posts first_account = Account.first Post.all.each { |p| p.update_attribute(:account, first_account) } end # ... end
そして、 Post モデルに戻って、関連を設定し、いくつかのバリデーションを追加しましょう。
# models/post.rb class Post < ActiveRecord::Base belongs_to :account validates_presence_of :title validates_presence_of :body end
さて、再びデータベースマイグレーションを実行しましょう。
sample_blog $ padrino rake ar:migrate == AddAccountToPost: migrating =============================================== -- change_table(:posts) == AddAccountToPost: migrated (0.0009s) ====================================== 7:04 => Executing Rake ar:migrate ...
我々の投稿は、いま、適切な関連とバリデーションを持っています。我々はさらに、既に出来ている Padrino の管理画面にもぐりこんで、投稿とアカウントの関連付けのためにいくつか変更を加えなければなりません。
続いて admin/controllers/posts.rb を見てみましょう。 current_account を、新規投稿の作成時に含むようにします。
# admin/controllers/posts.rb Admin.controllers :posts do # ... post :create do @post = Post.new(params[:post]) @post.account = current_account if @post.save flash[:notice] = 'Post was successfully created.' redirect url(:posts, :edit, :id => @post.id) else render 'posts/new' end end # ... end
一緒に、投稿のビューを、先ほどの変更点、作者を表示できるように変更します。
# 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) .details .author Posted by #{@post.account.email} %p= link_to 'View all posts', url_for(:posts, :index)
# 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) .details .author Posted by #{post.account.email}
では、別のユーザを追加してみましょう。 http://localhost:3000/admin をもう一度開き、 Account タブをクリックします。そしてアカウントを新規作成します。いま、あなたは、複数のユーザーと投稿を利用できることでしょう!
また、この変更の影響を、 http://localhost:3000/posts を見てみて確認してみましょう。新規作成された投稿は、投稿者と関連づいているはずです。
Site Layout
いま、アプリケーションは適切に設定され、サーバーもスタートしましたので、基本的なスタイルシートとレイアウトを作成し、継続的な開発のための準備をしましょう。
まず、我々のアプリケーションで使うレイアウトを作成します。レイアウトとは、各ルーティングごとに、コンテンツのテンプレートが投げ込まれる (yield される) コンテナーとして動作します。レイアウトは、アプリケーションの各ページでの、一貫した構造を作るために使われることが多いでしょう。レイアウトを作成するには、 app/views/layouts ディレクトリにファイルを追加します:
# 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
このレイアウトは、ブログの基本的な構成を作り、また我々のサイトの見栄えや振る舞いをコントロールするため必要な stylesheet や JavaScript を要求しています。また、このレイアウトには、検索などのためのダミーの要素や、スタブを用意してありますので、読者の練習のためにぜひお使いください。
次に、我々はスタイルシートのセットアップをする必要があるでしょう。このデモのために使うスタイルは2つあります。最初のものは、 Eric Meyers による「一般的」 CSS reset です。 スタイルシートの全容 は、 sample blog repository で見つけることができます。これを、 public/stylesheets/reset.css に配置してください。
二つ目のスタイルシートは、我々のスタイルシートのルック・アンド・フィールをより良くするものです。 スタイルシートの全容 は、こちらも sample blog repository にあり、これは app/stylesheets/application.sass に配置してください。
このレイアウトと2つのスタイルシートのおかげで、このブログの見た目はより強化されるでしょう! http://localhost:3000/posts を見て再確認してみてください。
RSS Feed を生成する
最後に、アプリケーションをデプロイする前に、 RSS と Atom のフィードをセットアップし、読者が我々のブログを購読できるようにしましょう。フィードのために、我々は posts コントローラに立ち戻って、 provides オプションを index ブロックに追加する必要がでてきます。下記のオプションは、ルーティングに対して、 HTML, RSS, Atom のフォーマットで表示できるようにせよ、と示すことになります。
# app/controllers/posts.rb SampleBlog.controllers :posts do ... get :index, :provides => [:html, :rss, :atom] do @posts = Post.all(:order => 'created_at desc') render 'posts/index' end ... end
この書き方により、レンダリングエンジンに対し、 RSS や Atom フォーマットで描画することの明示を省略できることに注目してください。
index.haml ファイルに立ち戻って、 「auto_discovery_link_tag」 ヘルパーを用いて RSS への参照を記述しましょう。
# app/views/posts/index.haml - @title = "Welcome" - content_for :include do = feed_tag(:rss, url(:posts, :index, :format => :rss),:title => "RSS") = feed_tag(:atom, url(:posts, :index, :format => :atom),:title => "ATOM") #posts= partial 'posts/post', :collection => @posts
次に、 atom 向けのテンプレートを、 builder を使って作成します:
# 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
RSS 向けのテンプレートも同様に作成できます:
# 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 で、フィードが利用できることを確認できます。これで、 RSS と Atom のフィードをブログで利用できるようになりました!
アプリケーションのデプロイ
これまでの経緯で、我々の基本的なブログは構築されたので、我々はアプリケーションをデプロイし、全世界に公開しなければなりませんね! そうするためのもっとも簡単な、かつ無料の方法は、 Heroku のようなサービスを使うことです。今すぐ、 Heroku に我々のアプリケーションをデプロイしましょう。
Heroku を始める最善のやり方は、 Heroku Quickstart Guide に従うことです。ガイドで説明されているとおり、 Git がインストールされていて、 Heroku account がセットアップされていて、 かつ Heroku gem がインストールされている ことを、このチュートリアルを続ける前に確認してください。
いま、 Heroku にデプロイするために、アプリケーションは Git リポジトリとしてセットされなければなりません:
sample_blog $ git init sample_blog $ git add . sample_blog $ git commit -m "initial commit for app"
これで Git リポジトリとして初期化されたので、すべてのコンテンツを add し、リポジトリにコミットしましょう。次に、アプリケーションは Heroku に対してもセットアップされなければなりません。
sample-blog $ heroku create --stack bamboo-ree-1.8.7 sample-blog $ git push heroku master
これで全てです。いま、あなたのアプリケーションは Heroku で動いています!
heroku open を打ち込み、あなたのサイトをブラウザで見てみましょう……。
しかし、現在では、 Padrino のデフォルトは SQLite ですが、 Heroku は PostgreSQL しかサポートしないため、我々は pg を Gemfile の依存関係として追加する必要があります。
# Gemfile group :production do gem 'pg' end
pg gem のインストールを避けるために、あなたは以下のコマンドをローカルマシンで実行することができます。
sample-blog $ bundle install --without production(ただし、 Heroku で利用する場合、 Gemfile.lock が適切に pg への依存関係を記述していなければ push 自体ができませんので、一度はプロダクションで 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 }
さらに、 padrino rake コマンドを実行できませんので、 Rakefile を作成する必要もあります:
# Rakefile require File.dirname(__FILE__) + '/config/boot.rb' require 'thor' require 'padrino-core/cli/rake' PadrinoTasks.init
padrino rake gen コマンドで同じものができます。
Sass を利用したい場合、 lib/sass_init.rb が存在しているなら以下の一行を追加してください。
app.use Sass::Plugin::Rack
最後に、インタラクティブにアカウントを作成できないので、 seed.rb もいじくる必要があります:
# db/seeds.rb email = "[email protected]" password = "admin" shell.say "" account = Account.create(:email => email, :name => "Foo", :surname => "Bar", :password => password, :password_confirmation => password, :role => "admin") if account.valid? shell.say "=================================================================" shell.say "Account has been successfully created, now you can login with:" shell.say "=================================================================" shell.say " email: #{email}" shell.say " password: #{password}" shell.say "=================================================================" else shell.say "Sorry but some thing went worng!" shell.say "" account.errors.full_messages.each { |m| shell.say " - #{m}" } end shell.say ""
seed で利用する値はご自由に変更してください。
いま、以下のコマンドをコンソールに打ち込みましょう:
sample_blog $ git add . sample_blog $ git commit -m "Added Postgres support" sample_blog $ git push heroku master
そうして、 migrations/seeds を実行しましょう:
sample_blog $ heroku rake ar:migrate sample_blog $ heroku rake seed
こういった感じに表示されるはずです:
sample_blog $ heroku rake ar:migrate (in /disk1/home/slugs/151491_a295681_03f1/mnt) => Located locked Gemfile for production == CreateAccounts: migrating ================================================= -- create_table("accounts", {}) -> 0.0185s == CreateAccounts: migrated (0.0229s) ======================================== == CreatePosts: migrating ==================================================== -- create_table("posts", {}) -> 0.0178s == CreatePosts: migrated (0.0218s) =========================================== == AddAccountToPost: migrating =============================================== -- change_table(:posts) -> 0.0026s == AddAccountToPost: migrated (0.0028s) ====================================== MacBook:sample_blog DAddYE$ heroku rake seed (in /disk1/home/slugs/151491_7576c59_03f1/mnt) => Located locked Gemfile for production ================================================================= Account has been successfully created, now you can login with: ================================================================= email: [email protected] password: admin =================================================================
さて、今再び、新しくデプロイされたアプリケーションを開いてみましょう:
sample_blog $ heroku openEnjoy!


