Last-modified: 2010-09-18 (土) 17:48:08 (1h)

RailsGuidesをゆっくり和訳してみたよ

Getting Started with Rails

原文

http://guides.rubyonrails.org/getting_started.html

Railsのはじめ方(Getting Started with Rails)

このガイドはRuby on Railsを立ち上げし、実行することまでを網羅してます。
読んだ後、以下のことに精通するでしょう。

  • Railsのインストール、新規Railsアプリの作成、DBへの接続
  • Railsアプリの一般的なレイアウト
  • MVCの基本的な原則(モデル、ビュー、コントローラ)とRESTful設計
  • Railsアプリの開始点を生成を素早く行う方法

このガイドはRails3.0に基づいています。
古いバージョンのRailsでは動作しないコードもあるでしょう。

1 ガイドの仮定(Guide Assumptions)

このガイドは、Railsアプリをスクラッチから作りたい初心者向けです。
これは、何かしらRailsの経験があるとは仮定していません。
しかしながら、最大限に使うために、いくつかの前提条件をインストールしておく必要があります:

Ruby 1.8.7 p248 と p249には、Rails 3.0をクラッシュさせるマーシャリングのバグがあることに注意して下さい。
Ruby Enterprise Editionは1.8.7-2010.02から修正されています。
1.9.1はRails 3.0は完全なセグメンテーション違反なので、1.9.xでRails3を使いたいなら、順調にするために1.9.2に飛んで下さい。

RailsはRubyプログラミング言語上で実行されるWebアプリケーションフレームワークです。
Rubyの経験が無い場合、Railsに飛び込むことで急激な学習曲線にぶつかるでしょう。
Railsは、Rubyを使った経験がない人が、魔法のようにWebアプリを作成する方法を変革するつもりはありません。
以下を含む、Rubyの学習のための良い無料のリソースがインターネット上にあります:

2 Railsとは?(What is Rails?)

RailsはRuby言語で書かれているウェブ開発フレームワークです。
すべての開発者が始めるにあたって必要なものを仮定をすることによって
Webアプリのプログラミングを簡単にするように設計されます。
他の多くの言語やフレームワークが実現するよりもっと少ないコードで書けます。
経験豊富なRails開発者はまた、Webアプリの開発がもっと楽しくなると報告しています。

Railsは自由なソフトウェアです。
すなわちそれは、ある物事を行うための"最良の"方法である、と想定していて、
その最良の方法を奨励するため-そしていくつかのケースでの選択肢を狭めるため-に設計されています。
"Rails道"を学べば、おそらく生産性の驚異的な増加を発見するでしょう。
もし他の言語からRailsの開発に古い習慣を持ち込み、他の場所で学んだパターンを使用しようとする場合は、幸せな経験が出来ないでしょう。

Railsの哲学には、いくつかの指針となる原則が含まれます:

  • DRY-"Don’t Repeat Yourself"(同じことを繰り返すな) -同じコードを何度も書くのは悪いことを示唆しています。
  • Convention Over Configuration(設定より規約)-無限の構成ファイルを介して全事象の微調整させるつもりはなく、
    あなたが何がしたいかについてRailsが仮定することを意味しています。
  • RESTはWebアプリのベストパターンです。-アプリにおいて、リソースと標準のHTTP動作周りを整理移動する最速の方法です。

2.1 MVCの設計(The MVC Architecture)

Railsはモデル、ビュー、コントローラ、普通はMVCと呼ばれるアーキテクチャで編成されています。
MVCは以下の利点があります:

  • ユーザーインターフェイスからビジネスロジックの分離
  • 容易にコードのDRYを保つ
  • 異なる種類のコードをのメンテナンスを容易にし、わかりやすくします。

2.1.1 モデル
モデルは、アプリの情報(データ)とデータを操作するためのルールを司ります。
Railsの場合には主に、対応するデータベーステーブルとの相互作用のルールを管理するため使用されます。
ほとんどのケースでは、データベース内の1つのテーブルはアプリ内の1つのモデルに対応します。
アプリのビジネスロジックの大部分はモデルに集中されます。

2.1.2 ビュー
ビューは、アプリのユーザーインターフェイスを表しています。
Railsでは、ビューは多くの場合、埋め込みのRubyコードのHTMLファイルであり、データの表示のみに関連するタスクを実行します。
アプリへのリクエストをするWebブラウザや他のツールに、データを提供するジョブを処理します。

2.1.3 コントローラー
コントローラはモデルとビューとの間の「接着剤」を提供します。
Railsでは、Webブラウザからのリクエストを処理するために応答し、
データ用のモデルに問い合わせし、表示用のビューにそのデータを渡します。

2.2 Railsのコンポーネント(The Components of Rails)

Rails以下を含むWebアプリ作成のためのコンポーネントのフルスタックを提供します:

  • Action Pack
    • Action Controller
    • Action Dispatch
    • Action View
  • Action Mailer
  • Active Model
  • Active Record
  • Active Resource
  • Active Support
  • Railties

2.2.1 Action Pack
Action Packは、Action Controller、Action View、Action Dispatchを含む単一のgemです。
"MVC"の"VC"部分です。

2.2.2 Action Controller
Action ControllerはRailsアプリ内のコントローラを管理するコンポーネントです。
Action Controllerフレームワークは、Railsアプリへのリクエストを処理し、
パラメータを抽出して、目的のアクションに発送します。
Action Controllerによって提供されるサービスは、セッション管理やテンプレートのレンダリング、リダイレクトの管理などがあります。

2.2.3 Action View
Action ViewはRailsアプリのビューを管理します。
デフォルトでHTMLおよびXMLどちらの出力も作成することができます。
Action Viewはテンプレートのレンダリングを管理し、そこにはネストされた部分テンプレートや、組み込みのAJAXのサポートも含まれています。

2.2.4 Action Dispatch
Action DispatchはWebリクエストのルーティングを処理し、あなたのアプリケーションや、他のRackアプリケーションに必要に応じて送出します。

2.2.5 Action Mailer
電子メールサービスを構築するためのフレームワークです。
受信した電子メールを処理したり、柔軟なテンプレートに基づいて簡単なtextや複雑なmultipartのEメールを送信したりすることができます。

2.2.6 Active Model
Active RecordのようなAction Pack gemサービスと、Object Relationship Mapping gemの間の
定義されたインターフェイスを、Active Modelは提供します。

2.2.7 Active Record
Active RecordはRailsアプリでのモデルの基礎です。
データベースの独立性、基本的なCRUD機能、高度な検索機能、別のモデルを関連付ける機能等を提供します。

2.2.8 Active Resource
ビジネスオブジェクトとRESTfulなWebサービス間の接続を管理するためのフレームワークを提供します。
CRUDセマンティクスによって、ウェブ上のリソースをローカルオブジェクトにマップする方法を実現します。

2.2.9 Active Support
Active Supportは、ユーティリティクラスの豊富なコレクションと標準のRubyライブラリの拡張で、
Rails内のコアなコードやあなたのアプリの両方で、使用されます。

2.2.10 Railties
Railtiesは、新しいRailsのアプリの作成やRailsアプリに様々なフレームワークを接着する、コアRailsコードです。

2.3 REST

RestはRepresentational State Transferの略で、RESTfulなアーキテクチャの基盤です。
これはRoy Fielding氏の博士論文「建築スタイルとネットワーク上のソフトウェアアーキテクチャ」に基づくと一般的に考えられています。
論文を読むことが出来ますが、Rails内でのRESTは2つの主要原則に集約されます:

  • リソースを表すために、URLのようなリソース識別子を使用します。
  • システムコンポーネント間で、リソースの状態の表現を転送します。

例えば、Railsアプリで以下のようなリクエストは:

DELETE /photos/17

IDが17のphotoのリソースを参照し、必要なアクション-リソースの削除-を示すと理解されるでしょう。
RESTは、Webアプリのアーキテクチャのための自然なスタイルであり、
Railsは、RESTfulな複雑さとブラウザの癖からあなたを保護します。

アーキテクチャのスタイルとしてRESTの詳細についてもっと知りたい場合、これらのリソースはフィールディングの論文よりも親しみやすいです:

3 新しいRailsプロジェクトの作成(Creating a New Rails Project)

このガイドを進めていくなら、(非常に)シンプルなウェブログである、 blog と呼ばれるRailsプロジェクトを作成しましょう。
アプリの構築を開始する前に、Rails自体がインストールされていることを確認する必要があります。

3.1 Railsのインストール(Installing Rails)

ほとんどのケースでは、Railsをインストールする最も簡単な方法はRubyGemsを活用することです:

通常、rootユーザーとしてこれを実行します:
# gem install rails

Rails 3.0.0-betaでは、rubygemsのバグから、手動でRails自体の依存関係をインストールする必要があります。
コマンドを実行するために3.0 Release Notesを読んで下さい。

Windows上で作業している場合は、Instant Railsのインストールが簡単に見えるでしょう。
しかし、Instant Rails]のリリースは、実際のRailsのバージョンより深刻な後れを取る傾向にあるので注意してください。
また、Windows上でのRails開発は他のOSに比べてより快適なように見えるでしょう。
可能であるならば、Rails開発環境にWindowsを使用する代わりに、Linuxの仮想マシンのインストールと使用を、お勧めします。

3.2 ブログアプリケーションの作成(Creating the Blog Application)

このガイドを使用する最善の方法は、各ステップの順番通りに行い、
このサンプルアプリケーションを作成するために必要なコードやステップは、省略されていないので、
文字通り、ステップバイステップで続けることができます。
完成したコードを参照する必要がある場合、Getting Started Codeからダウンロードできます。

まず初めに、ターミナルを開き、ファイル作成権限があるフォルダに移動して、タイプします:

$ rails new blog

これはblogディレクトリ内にBlogという名前のRailsアプリケーションを作るでしょう。

rails -h を実行することで、Railsアプリケーションビルダが受け入れる全てのスイッチを見れます。

ブログのアプリを作成した後、作業を続けるため、直接そのフォルダに移動します:

$ cd blog

いずれの場合でも、Railsは blog という名前のフォルダを作業ディレクトリ内に作成するでしょう。
そのフォルダを開き、その内容を探索してみましょう。
このチュートリアルでは、多くの作業は app/ フォルダ内で発生します。
デフォルトで新しいアプリケーション内にRailsが作成する各フォルダの機能の基本的な概要はこの通りです:

File/Folder目的
Gemfileこのファイルは、あなたのRailsアプリケーションに必要なgem依存が何かを指定することが出来ます。
README.rdocアプリケーションのための簡単な取扱説明書です。どのように設定すると、アプリケーションがどう動くかを他社に伝えるために使います。
Rakefile端末から実行することができるバッチジョブが含まれます。
app/あなたのアプリケーションのコントローラ、モデル、ビューが含まれます。このガイドの残りの部分にでは、ここにフォーカスします。
config/アプリの実行時のルール、ルーティング、データベース、および他の部分の設定をします。
config.ruアプリケーションの起動のために使われるRackベースのサーバーのためのRackの設定。
db/現在のデータベースのスキーマをデータベースマイグレーション(移行)として示します。マイグレーションについては、まもなく学びます。
doc/あなたのアプリケーションのための詳細なドキュメントです。
lib/拡張モジュール(このガイドでは扱いません)。
log/アプリケーションのログファイル。
public/世界中に公開される、唯一のフォルダです。イメージ、JavaScript、CSS、およびその他の静的ファイルが格納されます。
script/アプリケーションの起動や、デプロイ、アプリケーションの実行をするためのrailsスクリプトが含まれます。
test/Unit testやfixture、その他のテスト用の仕組みです。Testing Rails Applicationsで網羅されてます。
tmp/一時的なファイル。
vendor/サードパーティのコードを配置します。典型的なRailsアプリでは、RubyGems、Railsのソースコード(プロジェクトにインストールした場合)、追加でパッケージ化された機能を含むプラグイン、を含みます。

3.3 必要なgemのインストール(Installing the Required Gems)

デフォルトではRailsアプリケーションは、Bundlerでgemの依存関係を管理します。
生成された Gemfile 内にあるもの以外のgemの必要は無いので、準備のために以下を直接実行できます。

bundle install

3.4 データベースの設定(Configuring a Database)

データベースとやり取りするRailsアプリにだけついて。
使用するデータベースには、設定ファイルである config/database.yml が指定されています。
新しいRailsアプリでこのファイルを開くと、SQLite3を使用するデフォルトのデータベース設定を見ることが出来ます。
そのファイルは、Railsがデフォルトで実行できる3つの異なった環境のセクションを含みます:

  • development 環境は、手動でアプリケーションとの対話するために、開発用コンピュータ上で使用されます。
  • test 環境は、自動テストを実行するために使用されます。
  • production 環境は、世界中に公開するために、アプリケーションをデプロイする時に使われます。

3.4.1 SQLite3 データベースの設定

Railsには、軽量なサーバ不要のDBアプリであるSQLite3のサポートが付属しています。
忙しいproduction環境ではSQLiteでは過負荷になるかもしれませんが、developmentおよびtestではいい感じに動作します。
新しいプロジェクトの作成時、RailsはデフォルトでSQLiteデータベースを使用しますが、後でいつでも変更することができます。

デフォルトの設定ファイル(config/database.yml)のdevelopment環境用の接続情報のセクションです:

development:
  adapter: sqlite3
  database: db/development.sqlite3
  pool: 5
  timeout: 5000

設定なしに動くので、このガイド内ではデータストレージとしてSQLite3 データベースを使います。
Railsはまた"箱から出してすぐ使える"ようにMySQLとPostgreSQLをサポートしており、多くのデータベースシステム用のプラグインがあります。
production環境内でデータベースを使うなら、Railsはほとんどの場合、そのアダプタを持っています。

3.4.2 MySQLデータベースの設定

用意済みのSQLite3データベースの代わりにMySQLを使う場合は、config/database.ymlがチョビっと違います。
これはdevelopment環境用の接続情報セクションです:

development:
  adapter: mysql2
  encoding: utf8
  database: blog_development
  pool: 5
  username: root
  password: 
  socket: /tmp/mysql.sock

開発用コンピュータのMySQLのインストールが、空のパスワードのrootユーザーを含んでいたなら、この設定で動くでしょう。
それ以外の場合は、必要に応じて、 development セクションで、ユーザ名とパスワードを変更します。

3.4.3 PostgreSQLデータベースの設定
最後に、PostgreSQLを選んだなら、 config/database.yml はPostgreSQL用にカスタマイズされるでしょう。

development:
  adapter: postgresql
  encoding: unicode
  database: blog_development
  pool: 5
  username: blog
  password: 

必要に応じて development セクションで、ユーザ名とパスワードを変更して下さい。

3.5 データベースの作成(Creating the Database)

今ではあなたのデータベースは設定され、Railsが空のデータベースを作成する時です。

rake のコマンドを実行することにより、これを行えます。~
$ rake db:create

これは db/ フォルダの内側に、developmentとtest SQLite3データベースを作成するでしょう。

Rakeは、Railsが多くのことに使用する汎用コマンドランナーです。
rake -T を実行することで、アプリケーションで使用可能なrakeコマンドの一覧を見ることができます。

4 Hello, Rails!

伝統的な新しい言語を開始地点の1つは、さっと画面上にいくつかのテキストを表示することで、
それを行うために、Railsアプリケーションサーバーを実行する必要があります。

4.1 Webサーバーを立ち上げよう(Starting up the Web Server)

実際には、機能的なRailsのアプリケーションをあなたはすでに持っています。
それを見るには、あなたの開発用マシン上でWebサーバを起動する必要があります。
以下を実行することによって、これを行うことができます:

$ rails server

これはデフォルトで、MongrelのWebサーバーのインスタンスを起動します。(他のWebサーバーも使用することができます)
アプリケーションを参照するために、ブラウザを開いてhttp://localhost:3000を入力してください。
Railsのデフォルト情報のページを見れるでしょう。

welcome画面

Webサーバーを停止するには、サーバーが走っているターミナルでCtrl+Cを押してください。
developmentモードなら、一般的にサーバーを停止する必要はありません。
ファイルに加えた変更はサーバーによって自動的に検知されます。

"Welcome aboard"ページは、新しいRailsアプリケーションのためのスモークテストです:
それは、正しくページを提供するために、ソフトウェアが充分に正しく設定されていることを確認します。
またアプリケーションの環境の概要を見るために、About your application’s environmentリンクをクリックできます。

4.2 Rails君、"Hello"と言って(Say “Hello”, Rails)

Railsに"Hello"と言わせるには、最低でも、コントローラとビューを作成する必要があります。
幸いなことに、1つのコマンドで行うことができます。
ターミナルで次のコマンドを入力します:

$ rails generate controller home index

Windows上の場合や、非標準的な方法でRubyをセットアップした場合は、
Rubyに、明示的にRailsの rails コマンドを渡す必要があります:ruby \path\to\rails controller home index

Railsは、 app/views/home/index.html.erb を含むいくつかのファイルを作成するでしょう。
これは、 home コントローラ内の index アクション(メソッド)の結果を表示するために使用されるテンプレートです。
このファイルをテキストエディタで開いて、下の一行のコードを含むように編集しましょう:

<h1>Hello, Rails!</h1> 

4.3 アプリケーションのHomeの設定(Setting the Application Home Page)

今ではコントローラーとビューを作成しました、"Hello Rails"を見たい時、Railsに伝える必要があります。
この場合、サイトのルートURLであるhttp://localhost:3000を訪れた時、"Welcome Aboard"スモークテストの代わりに"Hello Rails"を表示したいです。

これを実行する最初の手順は、アプリケーションのデフォルトのページを削除することです:

$ rm public/index.html

Railsが、コントローラーから生成した動的なページよりも、
優先的に public ディレクトリ内の静的ファイルを届けるので、このことが必要です。

さて、実際のホームがどこに位置するかをRailsに教えてあげる必要があります。
エディタで、 config/routes.rb を開いて下さい。
これは、あなたのアプリケーションのルーティングファイルであり、特別なDSL(ドメイン特化言語)から成り、
受信したリクエストをどのようにコントローラー、アクションに繋ぐかを、Railsに教えています。
このファイルはコメント行に多くのサンプルを含み、その内の一つは実際に、
どうやって特定のコントローラー、アクションをサイトのルートに接続するかを、見せてくれます。
:rootで始まる行を探し、コメントアウトし、以下のように変更してください:

Blog::Application.routes.draw do

  #...
  # You can have the root of your site routed with "root"
  # just remember to delete public/index.html.
  root :to => "home#index"

root :to => "home#index"はRailsに、homeコントローラーのindexアクションにrootアクションをマッピングするように伝えています。

今、ブラウザでhttp://localhost:3000に移動すると、Hello, Rails!を見ることが出来るでしょう。

ルーティングに関してより多くの情報が必要なら、Rails Routing from the Outside Inへ。

5 Scaffolding(足場)で、ササッと組み上げて動かしてみるよ(Getting Up and Running Quickly With Scaffolding)

Railsの scaffolding は、アプリケーションの主要ないくつか部分を生成するための素早い方法です。
単一の操作で、新しいリソースのための、モデル、ビュー、コントローラーを作りたいなら、scaffoldingはそれ作業のためのツールです。

6 リソースを作成します。(Creating a Resource)

blogアプリケーションの場合、scaffoldされたPostリソースを生成するとこから始められます。:これは、単一のブログの投稿を表します
これを行うには、端末で次のコマンドを入力します:

$ rails generate scaffold Post name:string title:string content:text

scaffoldingでササッと組み上げて動かせますが、生成された"全てにフィットする何か"のコードが、アプリケーションに完璧にフィットすることはありそうもないです。
ほとんどの場合には、生成されたコードをカスタマイズする必要があるでしょう。
多くの経験豊富なRails開発者は、完全にscaffoldingを避け、スクラッチからソースコードの大部分、全部を書くことを好みます。

scaffoldドジェネレータはフォルダにそって、アプリケーション内に15のファイルを構築し、更に1つを編集します。
これは、何を作成するかの早見表です。

File目的
db/migrate/20100207214725_create_posts.rb.rbDBにpostのテーブルを作るためのマイグレーション(あなたの場合、違うtimestampが名前に入ってるでしょう)
app/models/post.rbPostモデル
test/fixtures/posts.ymltestで利用するダミーのpost
app/controllers/posts_controller.rbPostコントローラー
app/views/posts/index.html.erb全てのpostのindexを表示するview
app/views/posts/edit.html.erb既存のpostを編集するためのview
app/views/posts/show.html.erb一つのpostを表示するview
app/views/posts/new.html.erb新しいpostを作るためのview
app/views/posts/_form.html.erbeditとnewビュー内で使われているフォームの、全体的なルック&フィール制御するためのパーシャル
app/helpers/posts_helper.rbpostビューから使われるHelper機能
test/unit/post_test.rbpostモデルのUnitTest用の道具
test/functional/posts_controller_test.rbpostコントローラーの機能テスト用の道具
test/unit/helpers/posts_helper_test.rbpostヘルパのUnitTest用の道具
config/routes.rbpost用のルーティング情報を含むように編集された
public/stylesheets/scaffold.cssscaffoldされたviewの見た目を良くするCSS

6.1 マイグレーションの実行(Running a Migration)

rails generate scaffoldコマンドで生成されるものの一つに、データベースのマイグレーションがあります。
マイグレーションは、データベースのテーブルを簡潔に作成および変更するように設計されているrubyのクラスです。
Railsはマイグレーションを実行するのにrakeコマンドを使用し、データベースにマイグレーションが適用された後でも、アンドゥできます。
マイグレーションファイルが作成された順番に処理されることを保証するために、ファイル名にタイムスタンプを含みます。

db/migrate/20100207214725_create_posts.rb (あなたの場合は、ちょっと違う名前かもなのを覚えておいてね)の中身を見たら、こうなってるでしょう。

 class CreatePosts < ActiveRecord::Migration
   def self.up
     create_table :posts do |t|
       t.string :name
       t.string :title
       t.text :content

       t.timestamps
     end
   end

   def self.down
     drop_table :posts
   end
  end 

上記マイグレーションは二つのメソッド、データベースにこのマイグレーションを実行した時に呼び出されるup、
あとでこのマイグレーションによる変更を戻す必要がある時に使われるdown、を生成します。
この場合、upコマンドはpostsテーブルを二つのstringカラムと、一つのtextカラムと共に作成します。
それはまた、レコードの作成及び更新の記録をつける、二つのtimestampフィールドを作成します。
Rails Database Migrationsガイド内で、マイグレーションの詳細な情報を見つけることができます。

この時点で、マイグレーションを実行するためのrakeコマンドを使用することができます:

$ rake db:migrate

Railsはこのマイグレーションコマンドを実行し、あなたにPostsテーブルを作成したことを伝えるでしょう。

== CreatePosts: migrating ====================================================
-- create_table(:posts)
   -> 0.0019s
== CreatePosts: migrated (0.0020s) ===========================================

デフォルトではdevelopment環境で作業しているので、 config/database.yml 内の development セクションに定義されているデータベースに、このコマンドが適用されるでしょう。

6.2 リンクの追加(Adding a Link)

既に作成したhomeページにpostを連携するために、homeページにリンクを追加することができます。

/app/views/home/index.html.erb を開き、以下のように修正します:~
<h1>Hello, Rails!</h1>
<%= link_to "My Blog", posts_path %>
link_to メソッドは、Railsの組み込みビューヘルパの一つです。~

表示用のテキストとリンク先-この場合はpostsへのパス、に基づいてハイパーリンクを作成します。

6.3 ブラウザでのPostsの動き(Working with Posts in the Browser)

今、postsを動かし始める準備が整いました。
そうするために、http://localhost:3000に行き、「My Blog」リンクをクリックします:

投稿のindex

これはRailsがpostsのindexビューをRailsがレンダリングした結果です。
現在、データベース内に一つも記事がありませんが、New Postリンクをクリックした場合、作成することができます。
その後、編集できたり、詳細を見たり、破壊したりできるとわかるでしょう。
これを制御する全てのロジックとHTMLは、たった一つのrails generate scaffoldコマンドによって作成されました。

developmentモード(これはあなたがデフォルトで作業している)は、ブラウザのリクエストごとにRailsがアプリケーションの
リロードをしているので、Webサーバーを停止したり再起動したりする必要はありません。
おめでとう、あなたは今railsに乗っています!今が、全てがどうやって動いてるのか見た時です。

6.4 モデル(The Model)

モデルファイルである app/models/post.rb は、これでわかるぐらい、単純です。:

class Post < ActiveRecord::Base
end

このファイルは大きくありません。-しかし、 Post クラスが ActiveRecord::Base を継承していることは注意しておいてください。
Active Recordは、基本的なデータベースのCRUD(Create, Read, Update, Destroy)操作と、データの検証だけでなく、
高度な検索をサポートや、他の複数のモデルへの関連付けを含む巨大な機能群を、あなたのRailsのモデルへ無償で供給します。

6.5 バリデーションの追加(Adding Some Validation)

Railsは、モデルに送信するデータのバリデーション(検証)を支援するためのメソッドを含みます。

app/models/post.rb を開いて、編集します。~
class Post < ActiveRecord::Base
  validates :name,  :presence => true
  validates :title, :presence => true,
                    :length => { :minimum => 5 }
end 

これらの変更は、全てのpostがnameとtitleを持ち、titleは少なくとも5文字の長さであることを確認するでしょう。
Railsは、カラムの存在または一意性、フォーマット、および関連するオブジェクトの存在、を含むさまざまな条件を、モデル内でバリデーションできます。

6.6 コンソールの使用(Using the Console)

アクション内のバリデーションを見てみるには、コンソールを使用することができます。
コンソールは、あなたのアプリケーションの環境でRubyのコードを実行できるコマンドラインツールです:

$ rails console

コンソールをロードした後で、アプリケーションのモデルを動作させるために使用することができます:

>> p = Post.create(:content => "A new post")
=> #<Post id: nil, name: nil, title: nil, content: "A new post", created_at: nil, updated_at: nil> 
>> p.save
=> false
>> p.errors
=> #<OrderedHash { :title=>["can't be blank", "is too short (minimum is 5 characters)"], :name=>["can't be blank"] }>

このコードは新しいPostのインスタンスの作成し、それを保存しようとし、
戻り値のfalseを得て(保存に失敗したことを示しています)、postのerrorsを検査することを示します。

終わったら、 exit とタイプして return を押して、コンソールを抜けて下さい。

development Webサーバーとは異なり、コンソールは自動的にそれぞれの行のコードを新たにロードしません。
コンソールを開いている間に、モデルに変更した時は reload! とタイプすれば、コンソールプロンプトがロードされます。

6.7 全てのPostsをリストする(Listing All Posts)

機能を見るのに最も簡単なのは、すべてのpostをリストするコードです。

app/controllers/posts_controller.rb を開き、indexアクションを見て下さい。~
def index
  @posts = Post.all

  respond_to do |format|
    format.html # index.html.erb
    format.xml { render :xml => @posts }
  end
end
Post.all は、現在のデータベース内にある全てポストを返すために Post モデルを呼びます。~

この呼び出しの結果は、postを格納している配列で、 @posts と呼ばれるインスタンス変数に保存されます。

Active Recordのレコードを見つけることの詳細については、
Active Record Query Interfaceを参照してください。

respond_to ブロックは、このアクションを呼び出すHTMLとXMLの両方を処理します。~

http://localhost:3000/posts.xmlをブラウズすれば、XML形式ですべてのpostが表示されるでしょう。
HTML形式は、アクション名に対応する名前である app/views/posts/ 内でビューを探します。
Railsは、ビューが利用可能なように、アクションからすべてのインスタンス変数を作成します。

app/view/posts/index.html.erb はこんな感じです。~
<h1>Listing posts</h1>

<table>
  <tr>
    <th>Name</th>
    <th>Title</th>
    <th>Content</th>
    <th></th>
    <th></th>
    <th></th>
  </tr>

<% @posts.each do |post| %>
  <tr>
    <td><%= post.name %></td>
    <td><%= post.title %></td>
    <td><%= post.content %></td>
    <td><%= link_to 'Show', post %></td>
    <td><%= link_to 'Edit', edit_post_path(post) %></td>
    <td><%= link_to 'Destroy', post, :confirm => 'Are you sure?', :method => :delete %></td>
  </tr>
<% end %>
</table>

<br />

<%= link_to 'New post', new_post_path %>

このビューは、コンテンツやリンクを表示するために、@posts配列の内容を反復処理します。
ビューで注意するいくつかのこと:

  • link_to は特定の宛先へのハイパーリンクを作成します。
  • edit_post_path と new_post_path は、RailsがRESTfulなルーティングの一部を提供するためのヘルパです。
    コントローラが含んでいるさまざまなアクションのための、これらのヘルパーを見るでしょう。

Railsの以前のバージョンでは、ページに挿入される前に、どんなHTMLもエスケープされるために
<%=h post.name %>を使わなければいけませんでした。
Rails 3.0では、これはデフォルトになりました。
エスケープしていないHTMLを得るためには、 <%= raw post.name %> を使います。

レンダリングプロセスの詳細については、Layouts and Rendering in Railsを参照してください。

6.8 レイアウトのカスタマイズ(Customizing the Layout)

ビューは、HTMLがWebブラウザにどうやって表示されるのかという話の一部に過ぎません。
Railsはまた、 layouts のコンセプトも持っていて、それは、ビューのコンテナです。
Railsがブラウザにビューをレンダリングする時、レイアウトのHTMLの内側にビューのHTMLを入れます。
Railsの以前のバージョンでは、script/generate scaffold コマンドが、postsコントローラー用に

app/views/layouts/posts.html.erb のような、コントローラー固有のレイアウトを作っていました。~

しかしながら、Rails3.0ではこれは変更されました。
アプリケーション固有の layout は、全てのコントローラーで使用され、 app/views/layouts/application.html.erb 内で見つけるができます。
このレイアウトをエディタで開き、 body タグを修正して下さい。

<!DOCTYPE html>
<html>
<head>
  <title>Blog</title>
  <%= stylesheet_link_tag :all %>
  <%= javascript_include_tag :defaults %>
  <%= csrf_meta_tag %>
</head>
<body style="background: #EEEEEE;">

<%= yield %>

</body>
</html> 
/posts ページを更新すると、ページに灰色の背景が表示されるでしょう。~

これと同じ灰色の背景色が、投稿のためのすべてのビューを通じて使用されるでしょう。

6.9 新規投稿を作成する(Creating New Posts)

新しい投稿を作成するということは、2つのアクションを含みます。
最初は、 new アクションで、空の Post オブジェクトをインスタンス化します:

def new
  @post = Post.new

  respond_to do |format|
    format.html # new.html.erb
    format.xml { render :xml => @post }
  end
end

new.html.erbビューは、この空の投稿をユーザーに表示します:

<h1>New post</h1>

<%= render 'form' %>

<%= link_to 'Back', posts_path %>

<%= render 'form' %> 行は、Rails内のパーシャルのための最初の導入です。
パーシャルは、様々な場所で再利用されるHTMLとRubyコードのスニペットです。
この場合、新しい投稿を作るためのフォームは、投稿を編集するためのフォームと基本的に同じで、
両方とも、nameとtitleのテキストフィールドと、contentのテキストエリアを、
新しい投稿を作成するためや、既存の投稿を更新するためのボタンと共に持っています。

views/posts/_form.html.erb ファイルを見れば、こんな感じでしょう。~
<%= form_for(@post) do |f| %>
  <% if @post.errors.any? %>
  <div id="errorExplanation">
    <h2><%= pluralize(@post.errors.count, "error") %> prohibited this post from being saved:</h2>
    <ul>
    <% @post.errors.full_messages.each do |msg| %>
      <li><%= msg %></li>
    <% end %>
    </ul>
  </div>
  <% end %>

  <div class="field">
    <%= f.label :name %><br />
    <%= f.text_field :name %>
  </div>
  <div class="field">
    <%= f.label :title %><br />
    <%= f.text_field :title %>
  </div>
  <div class="field">
    <%= f.label :content %><br />
    <%= f.text_area :content %>
  </div>
  <div class="actions">
    <%= f.submit %>
  </div>
<% end %>

このパーシャルは、呼ばれたビューファイル内で定義された全てのインスタンス変数を受け取ります。
この場合は、コントローラーは新しい Post オブジェクトを @post に割り当て、
これはビューとパーシャルの両方で、@postとして利用可能です。

パーシャルの他の情報は、Layouts and Rendering in Railsガイドを参照して下さい。

form_for ブロックは、HTMLフォームを作成するために使用されます。~

このブロック内では、フォーム上のさまざまなコントロールを作成するためのメソッドにアクセスしています。
例えば、f.text_field :name は、フォーム上にテキスト入力を作成し、表示されているインスタンスのname属性にそれを関連付けるように、Railsに指示を出します。
フォームが基づいているモデルの属性(この場合、name、title、content)としか、これらのメソッドを使用することができません。
コードをより簡潔にするため、また、明示的に特定のモデルのインスタンスのフォームを形成するため、Railsは生のHTMLより form_for を優先的に使用します。

form_for ブロックはまた、新しい投稿や投稿の編集をするなら、充分うまくやるぐらい賢く、~

HTML出力内で適切に、フォームのactionタグと送信ボタンの名前を設定します。

モデルに関連付けられていない任意のフィールドを表示するためにHTMLフォームを作成する必要があるなら、
モデルのインスタンスに必ずしも関連付けられているとは限らないフォームを構築するための、ショートカットを提供する form_tag メソッドを使用するべきです。

ユーザーがこのフォーム上のCreate Postボタンをクリックする時、ブラウザはコントローラの create メソッドに情報を送り返すでしょう。
(フォームがHTTP POSTリクエストで送信されているので、Railsは create メソッドを呼び出すことを知っています。これは前述した規約の一つです。)

def create
  @post = Post.new(params[:post])

  respond_to do |format|
    if @post.save
      format.html { redirect_to(@post,
                    :notice => 'Post was successfully created.') }
      format.xml { render :xml => @post,
                   :status => :created, :location => @post }
    else
      format.html { render :action => "new" }
      format.xml { render :xml => @post.errors,
             :status => :unprocessable_entity }
    end
  end
end

Railsが params ハッシュで利用できる、フォーム上でユーザによって埋められたデータから、 create アクションが新しい Post オブジェクトをインスタンス化します。
新しい投稿を保存するのに成功した後、 create は、ユーザーが要求した適切なフォーマットを返します。(この場合はHTML)
その後、ユーザーを結果のpostのshowアクションにリダイレクトし、ユーザーへの"Post was successfully created."という通知を設定します。

バリデーションエラーのために、投稿が正常に保存されないなら、ユーザーがエラーを修正し、再度挑戦するために、
コントローラーはユーザーをnewアクションにエラーメッセージと共に送り返します。

メッセージを他のアクションに持ち越すことができ、リクエストの状態の有用な情報をユーザーに提供するために、
"Post was successfully created."メッセージはRailsの flash ハッシュの内側に保存されます。(通常、単にフラッシュと呼ばれます。)

create の場合、ユーザーは実際に、投稿作成プロセス中にどんなページがレンダリングされるところも、見ることは無いでしょう。~

Railsはレコードを保存してすぐに、新しい投稿にリダイレクトされるからです。
フラッシュは次のアクションにメッセージを持ち越します、
これはユーザーがshowアクションにリダイレクトされた時に、"Post was successfully created."というメッセージが表示するためです。

6.10 個々の投稿を表示(Showing an Individual Post)

index ページの、ある投稿のshowリンクをクリックした時に、http://localhost:3000/posts/1のようなURLへ運ばれます。~

Railsはこれを、そのリソースのための show アクションの呼び出しだと認識し、:idパラメータとして1を渡します。
ここにshowアクションがあります:

def show
  @post = Post.find(params[:id])


  respond_to do |format|
    format.html # show.html.erb
    format.xml { render :xml => @post }
  end
end

showアクションは、idの値によってデータベース内の単一のレコードの検索するために Post.find を使用します。
レコードを検索した後、Railsは show.html.erb を使用して表示します:

<p class="notice"><%= notice %></p>

<p>
  <b>Name:</b>
  <%=h @post.name %>
</p>

<p>
  <b>Title:</b>
  <%=h @post.title %>
</p>

<p>
  <b>Content:</b>
  <%=h @post.content %>
</p>


<%= link_to 'Edit', edit_post_path(@post) %> | 
<%= link_to 'Back', posts_path %>

6.11 投稿記事の編集(Editing Posts)

新しい投稿の作成と同様に、投稿の編集も2つのプロセスです。
最初のステップは特定の投稿にくるedit_post_path(@post)というリクエストです。
これは、コントローラ内の edit アクションを呼び出します:

def edit
  @post = Post.find(params[:id])
end 

リクエストされた投稿を見つけると、Railsはそれを表示するために edit.html.erb ビューを使用します:

<h1>Editing post</h1>

<%= render 'form' %>

<%= link_to 'Show', @post %> |
<%= link_to 'Back', posts_path %>
<% end %>

繰り返しになりますが、newアクションと同様に、editアクションはformパーシャルを使い、
この時、フォームは、PostControllerにPUTアクションを行い、submitボタンは"Update Post"を表示するでしょう。

このビューで作られたフォームの送信は、コントローラー内の update アクションを呼び出すでしょう。

def update
  @post = Post.find(params[:id])

  respond_to do |format|
    if @post.update_attributes(params[:post])
      format.html { redirect_to(@post,
                    :notice => 'Post was successfully updated.') }
      format.xml { head :ok }
    else
      format.html { render :action => "edit" }
      format.xml { render :xml => @post.errors, 
                   :status => :unprocessable_entity }
    end
  end
end

updateアクションでは、Railsはまず、編集中のデータベースのレコードを見つけるために、:id パラメータをeditビューから受け取ります。

update_attributes の呼び出しでは、リクエストからパラメータの残りの部分をとり、このレコードに適用します。~

もし全てがうまくいけば、ユーザーは投稿のshowビューにリダイレクトされます。
何か問題があれば、再びそれらを修正するためにeditビューに戻します。

6.12 投稿の削除(Destroying a Post)

最後に、いずれかの destroy リンクをクリックすると、関連付けられたIDが destroy アクションに送信されます

def destroy
  @post = Post.find(params[:id])
  @post.destroy

  respond_to do |format|
    format.html { redirect_to(posts_url) }
    format.xml  { head :ok }
  end
end

Active Recordモデルのインスタンスの destroy メソッドは、データベースから対応するレコードを削除します。
削除した後に行うのは、表示するレコードがないので、Railsはユーザーのブラウザをモデルのためのindexビューにリダイレクトします。

7 二番目のモデルを追加する(Adding a Second Model)

今、scaffoldで構築されたモデルにどのようなものか見てきました、アプリケーションに2番目のモデルを追加する時が来ました。
2番目のモデルでは、ブログの投稿へのコメントを処理するでしょう。

7.1 モデルの生成(Generating a Model)

Railsのモデルは単数形の名前を使用し、対応するデータベースのテーブルには複数形の名前を使用します。
コメントを保持するモデルのために、Commentという名前を使うのは規約です。
scaffoldで設定された全体の仕組みを使用したくない場合でも、ほとんどのRails開発者はジェネレータを使用してモデルとコントローラのようなものを作成します。
新しいモデルを作成するには、端末でこのコマンドを実行しなさい。

$ rails generate model Comment commenter:string body:text post:references

このコマンドは、4つのファイルが生成するでしょう:

  • app/models/comment.rb - モデル
  • db/migrate/20100207235629_create_comments.rb - マイグレーション
  • test/unit/comment_test.rb と test/fixtures/comments.yml - テストハーネス

まず、comment.rbを見てみましょう:

class Comment < ActiveRecord::Base
  belongs_to :post
end

これは以前に見たpost.rbモデルに非常に似ています。
違いは、belongs_to :postの行で、Active Recordのアソシエーション(関連付け)を設定します。
このガイドの次のセクションでアソシエーションについて少し学ぶでしょう。

モデルに加えて、Railsは対応するデータベーステーブルを作成するマイグレーションも作成します:

class CreateComments < ActiveRecord::Migration
  def self.up
    create_table :comments do |t|
      t.string :commenter
      t.text :body
      t.references :post

      t.timestamps
    end
  end

  def self.down
    drop_table :comments
  end
end

t.references の行は2つのモデル間のアソシエーションのための外部キーカラムを設定します。
先に進み、マイグレーションを実行します:

$ rake db:migrate

Railsは、現在のデータベースに対してまだ実行されていないマイグレーションを実行するのに充分賢く、
この場合は、以下が見れるでしょう。

== CreateComments: migrating =================================================
-- create_table(:comments)
   -> 0.0017s
== CreateComments: migrated (0.0018s) ========================================

7.2 関連付けモデル(Associating Models)

Active Record のアソシエーションは、2つのモデル間の関係を簡単に宣言することができます。
コメントや投稿の場合は、この方法で関係を書くことができます:

  • 各commentは1つのpostに属しています
  • 1つのpostは、多くのcommentを持つことができます

実際には、これは、Railsがこのアソシエーションを宣言するために使用する構文に非常に近いものです。
各commentがPostに所属できるようにするCommentモデル内のコードの行を既に見てきました:

class Comment < ActiveRecord::Base
  belongs_to :post
end

アソシエーションの反対側に追加するために post.rb を編集する必要があるでしょう:

class Post < ActiveRecord::Base
  validates :name,  :presence => true
  validates :title, :presence => true,
                    :length => { :minimum => 5 }

  has_many :comments
end

これらの2つの宣言は、自動的な動作をいい具合に有効にします。
たとえば、 @post インスタンス変数にpostを格納している場合は、 @post.comments 配列としてそのpostに属するコメントを全て取得できます。

Active Record アソシエーションの詳細については、Active Record Associationsガイドを参照してください。

7.3 コメントのためのルーティングの追加(Adding a Route for Comments)

homeコントローラーと同様に、コメントが見るためにどこに移動するべきか、Railsに伝えるために、ルーティングを追加する必要があるでしょう。

config/routes.rb ファイルを再度開いて下さい、~

scallofdジェネレーターによって、ファイルの一番上付近のpostsのために自動的に追加、編集された、次のようなresources :postsエントリを見るでしょう。

resources :posts do
  resources :comments
end

これはposts内でネストされた resource として、commentsを作成します。
これは記事やコメントの間に存在する階層関係を捉えた別の部分です。

ルーティングに関して他の情報は、Rails Routing from the Outside Inガイドを参照してください。

7.4 コントローラの生成(Generating a Controller)

モデルがあれば、マッチするコントローラを作成することに注意を向けることができます。
繰り返しになりますが、このためのジェネレータがあります:

$ rails generate controller Comments

これは4つのファイルと1つの空のディレクトリを作成します:

  • app/controllers/comments_controller.rb - コントローラー
  • app/helpers/comments_helper.rb - viewヘルパ
  • test/functional/comments_controller_test.rb - コントローラー用の機能テスト
  • test/unit/helpers/comments_helper_test.rb - ヘルパ用のユニットテスト
  • app/views/comments/ - index actionのview

他のブログと同様、読者は投稿を読んだあとに、直接コメントを作り、コメントを追加し、
リストされたコメントを見るために、投稿のshowページに送り返されるでしょう。
このために、 CommentsController は、コメントを作成するためとSPAMコメントを削除するためのメソッドを提供するでしょう。

そこでまず、新しいコメントを作成するために、Postのshowテンプレート(/app/views/posts/show.html.erb)を結びつけるでしょう。

<p class="notice"><%= notice %></p>

<p>
  <b>Name:</b>
  <%= @post.name %>
</p>

<p>
  <b>Title:</b>
  <%= @post.title %>
</p>

<p>
  <b>Content:</b>
  <%= @post.content %>
</p>

<h2>Add a comment:</h2>
<%= form_for([@post, @post.comments.build]) do |f| %>
  <%= f.error_messages %>

  <div class="field">
    <%= f.label :commenter %><br />
    <%= f.text_field :commenter %>
  </div>
  <div class="field">
    <%= f.label :body %><br />
    <%= f.text_area :body %>
  </div>
  <div class="actions">
    <%= f.submit %>
  </div>
<% end %>

<%= link_to 'Edit Post', edit_post_path(@post) %> |
<%= link_to 'Back to Posts', posts_path %> | 
 

これは、Postのshowページ上に、新しいコメントを作成するフォームを追加します。
そrはCommentsController の create アクションを呼ぶでしょう。
結びつけましょう:

class CommentsController < ApplicationController
  def create
    @post = Post.find(params[:post_id])
    @comment = @post.comments.create(params[:comment])
    redirect_to post_path(@post)
  end
end

postsのコントローラーより、少し複雑に見えるでしょう。
それはネストを設定した副作用です。
コメントへの各リクエストは、そのコメントが添付されたpostを追跡し続けなければなりません。
問題の投稿を取得するためのPostモデルのための、最初のfindアクションのように。

また、このコードはアソシエーションのために利用可能なメソッドをいくつかを活用しています。
コメントを作成、保存するために、 @post.comments 上の create メソッドを使います。
これは、特定の投稿に属するように、自動的にコメントを結びつけるでしょう。

新しいコメントの後、 post_path(@post) ヘルパを使い、元のpostに送り返します。
既に見たように、これは show.html.erb テンプレートをレンダリングする時に、PostsController の show アクションを呼び出します。
これはコメントを表示したい場所で、 app/views/posts/show.html.erb に追加しましょう。

<p class="notice"><%= notice %></p>

<p>
  <b>Name:</b>
  <%= @post.name %>
</p>

<p>
  <b>Title:</b>
  <%= @post.title %>
</p>

<p>
  <b>Content:</b>
  <%= @post.content %>
</p>

<h2>Comments</h2>
<% @post.comments.each do |comment| %>
  <p>
    <b>Commenter:</b>
    <%= comment.commenter %>
  </p>

  <p>
    <b>Comment:</b>
    <%= comment.body %>
  </p>
<% end %>

<h2>Add a comment:</h2>
<%= form_for([@post, @post.comments.build]) do |f| %>
  <%= f.error_messages %>

  <div class="field">
    <%= f.label :commenter %><br />
    <%= f.text_field :commenter %>
  </div>
  <div class="field">
    <%= f.label :body %><br />
    <%= f.text_area :body %>
  </div>
  <div class="actions">
    <%= f.submit %>
  </div>
<% end %>

<br />

<%= link_to 'Edit Post', edit_post_path(@post) %> |
<%= link_to 'Back to Posts', posts_path %> | 

これでブログに投稿とコメントを追加し、正しい場所に表示することが出来ます。

8 リファクタリング(Refactoring)

この時点で、動作するPosts と Comments を持っていますが、

app/views/posts/show.html.erb を見ると、長くて厄介です。~

クリーンアップするためにパーシャルを使用することができます。

8.1 パーシャルコレクションのレンダリング(Rendering Partial Collections)

まず、投稿のための全てのコメントの表示を抽出するために、コメントのパーシャルを作りましょう。

app/views/comments/_comment.html.erb ファイルを作り、その中に次のことを書きます:~
<p>
  <b>Commenter:</b>
  <%= comment.commenter %>
</p>

<p>
  <b>Comment:</b>
  <%= comment.body %>
</p>

次に app/views/posts/show.html.erb 内で、次のように変更します:

<p class="notice"><%= notice %></p>

<p>
  <b>Name:</b>
  <%= @post.name %>
</p>

<p>
  <b>Title:</b>
  <%= @post.title %>
</p>

<p>
  <b>Content:</b>
  <%= @post.content %>
</p>

<h2>Comments</h2>
<%= render :partial => "comments/comment",
           :collection => @post.comments %>

<h2>Add a comment:</h2>
<%= form_for([@post, @post.comments.build]) do |f| %>
  <%= f.error_messages %>

  <div class="field">
    <%= f.label :commenter %><br />
    <%= f.text_field :commenter %>
  </div>
  <div class="field">
    <%= f.label :body %><br />
    <%= f.text_area :body %>
  </div>
  <div class="actions">
    <%= f.submit %>
  </div>
<% end %>

<br />

<%= link_to 'Edit Post', edit_post_path(@post) %> |
<%= link_to 'Back to Posts', posts_path %> |
 

これは、 @post.comments コレクション内の全てのコメントごとに一回ずつ、

app/views/comments/_comment.html.erb 内のパーシャルをレンダリングするでしょう。~
render メソッドが、 @post.comments コレクションを繰り返し、~

パーシャルと同じ名前のローカル変数、この場合は表示するためにパーシャル内で利用可能なcomment、に各コメントを割り当てます。

8.2 パーシャルフォームのレンダリング(Rendering a Partial Form)

自身のパーシャルから、new commentのセクションを取り除きましょう、
また、 app/views/comments/_form.html.erb ファイルを作り、その中に、このように書きます:

<%= form_for([@post, @post.comments.build]) do |f| %>
  <%= f.error_messages %>

  <div class="field">
    <%= f.label :commenter %><br />
    <%= f.text_field :commenter %>
  </div>
  <div class="field">
    <%= f.label :body %><br />
    <%= f.text_area :body %>
  </div>
  <div class="actions">
    <%= f.submit %>
  </div>
<% end %>

そして、 app/views/posts/show.html.erb を次のようにします:

<p class="notice"><%= notice %></p>

<p>
  <b>Name:</b>
  <%= @post.name %>
</p>

<p>
  <b>Title:</b>
  <%= @post.title %>
</p>

<p>
  <b>Content:</b>
  <%= @post.content %>
</p>

<h2>Comments</h2>
  <%= render :partial => "comments/comment",
             :collection => @post.comments %>

<h2>Add a comment:</h2>
<%= render "comments/form" %>

<br />


<%= link_to 'Edit Post', edit_post_path(@post) %> |
<%= link_to 'Back to Posts', posts_path %> |
 

第二の render は、レンダリングしたいパーシャルテンプレート comments/form を定義します。
Railsは、文字列内の最初のスラッシュを見極め、

app/views/comments ディレクトリ内の _form.html.erb ファイルをレンダリングしたいことを理解するのに充分なぐらい賢いです。~

@post オブジェクトは、インスタンス変数として定義しているので、ビュー内でレンダリングされたパーシャルで、利用可能です。

9 コメントの削除(Deleting Comments)

ブログのもう一つの重要な機能は、スパムコメントを削除できることです。
このために、ビューのいくつかの種類のリンクと、CommentsController 内の DELETE アクションを実装する必要があります。

最初に、 app/views/comments/_comment.html.erb パーシャル内で、削除リンクを追加しましょう:

<p>
  <b>Commenter:</b>
  <%= comment.commenter %>
</p>

<p>
  <b>Comment:</b>
  <%= comment.body %>
</p>

<p>
  <%= link_to 'Destroy Comment', [comment.post, comment],
               :confirm => 'Are you sure?',
               :method => :delete %>
</p>

この新しい"Destroy Comment"リンクをクリックすると、DELETE /posts/:id/comments/:idを CoomentsController に発行するでしょう、
それではコントローラーに destroy アクションを追加しましょう:

class CommentsController < ApplicationController

  def create
    @post = Post.find(params[:post_id])
    @comment = @post.comments.create(params[:comment])
    redirect_to post_path(@post)
  end

  def destroy
    @post = Post.find(params[:post_id])
    @comment = @post.comments.find(params[:id])
    @comment.destroy redirect_to post_path(@post)
  end

end

destroy アクションは、探しているpostを見つけ、@post.comments コレクション内でcommentを検索し、
それをデータベースから削除し、そのpostのための show アクションに送り返すでしょう。

9.1 関連づいたオブジェクトの削除(Deleting Associated Objects)

ある投稿を削除したいなら、それと関連しているコメントもまた削除する必要があります。
そうしなければ、データベース内のスペースを占有してしまいます。
Railsは、これを達成するために、アソシエーションのdependentオプションを使えます。
以下のように、app/models/post.rb の Post モデルを修正して下さい:

class Post < ActiveRecord::Base
  validates :name,  :presence => true
  validates :title, :presence => true,
                    :length => { :minimum => 5 }
  has_many :comments, :dependent => :destroy
end

10 セキュリティ(Security)

ブログをオンラインで公開してても、誰でも投稿の追加、編集、削除と、コメントの削除が出来るでしょう。

Railsは、このような状況でいい感じに動く、とてもシンプルなHTTP認証システムを提供しています。
まずは、app/controllers/application_controller.rb 内で、シンプルなHTTPベース認証を有効にします:

class ApplicationController < ActionController::Base
  protect_from_forgery

  private

  def authenticate
    authenticate_or_request_with_http_basic do |user_name, password|
      user_name == 'admin' && password == 'password'
    end
  end

end

明示的に、ユーザー名とパスワードを好きなものに変更することができます。
コントローラーの全てで利用可能なように、ApplicationController の内側にこのメソッドを置きます。

認証されていない場合、 PostsController内で、様々なアクションへのアクセスをブロックする方法を持つことが必要で
Railsの before_filter メソッドを使えます、それはメソッドを実行し、それが許した場合のみ、
リクエストされたアクションへのアクセスを許すことを、Railsに指定できます。

before filterを使うために、PostsController の上部にそれを指定します。
この場合は、index と show を除く全てのアクションでユーザーに認証したいので、こう書きます

class PostsController < ApplicationController

  before_filter :authenticate, :except => [:index, :show]

  # GET /posts
  # GET /posts.xml
  def index
    @posts = Post.all
    respond_to do |format|
# 簡潔のためのスニペット

また、認証されたユーザーのみがコメントを削除することを許可したいので、
CommentsController 内に書きます:

class CommentsController < ApplicationController

  before_filter :authenticate, :only => :destroy

  def create
    @post = Post.find(params[:post_id])
# 簡潔のためのスニペット

今、新しい投稿を作成しようとしたら、BASIC HTTP認証チャレンジで挨拶されるでしょう:

BASIC HTTP認証チャレンジ

11 色々なモデルのフォームを組み立てる(Building a Multi-Model Form)

あなたの平均的なブログの他の機能は、投稿にタグを設定する機能です。
この機能を実装するために、あなたのアプリケーションは、単一のフォーム上で複数のモデルと対話する必要があります。
Railsはネストしたフォームをサポートします。

これを実証するために、作成した投稿の右に、それぞれの投稿に複数のタグを与えるためのサポートを追加しましょう。
まず、タグを保持するために新しいモデルを作成します:

$ rails generate model tag name:string post:references

再度、データベーステーブルを作成するためにマイグレーションを実行します:

$ rake db:migrate

次に、アソシエーションの逆側を作成するために post.rb を編集し、
投稿を介してタグを編集する予定だと(accepts_nested_attributes_for マクロを通じて)、Railsに伝えます:

class Post < ActiveRecord::Base
  validates :name,  :presence => true
  validates :title, :presence => true,
                    :length => { :minimum => 5 }
  has_many :comments, :dependent => :destroy
  has_many :tags

  accepts_nested_attributes_for :tags, :allow_destroy => :true,
    :reject_if => proc { |attrs| attrs.all? { |k, v| v.blank? } }
end
 

ネストされた属性の宣言の :allow_destroy オプションは、Railsに、ビュー上に"remove"チェックボックスの表示をすぐに構築できるように伝えます。
:reject_if オプションは、どの属性が空でも新しいタグを保存するのを阻止します。
views/posts/_form.html.erb を、タグを作るためのパーシャルをレンダリングするように修正する必要があるでしょう。

<% @post.tags.build %>
<%= form_for(@post) do |post_form| %>
  <% if @post.errors.any? %>
  <div id="errorExplanation">
    <h2><%= pluralize(@post.errors.count, "error") %> prohibited this post from being saved:</h2>
    <ul>
    <% @post.errors.full_messages.each do |msg| %>
      <li><%= msg %></li>
    <% end %>
    </ul>
  </div>
  <% end %>

  <div class="field">
    <%= post_form.label :name %><br />
    <%= post_form.text_field :name %>
  </div>
  <div class="field">
    <%= post_form.label :title %><br />
    <%= post_form.text_field :title %>
  </div>
  <div class="field">
    <%= post_form.label :content %><br />
    <%= post_form.text_area :content %>
  </div>
  <h2>Tags</h2>
  <%= render :partial => 'tags/form',
             :locals => {:form => post_form} %>
  <div class="actions">
    <%= post_form.submit %>
  </div>
<% end %>
 

何が起こっているか理解するのに簡単にするために、f in form_for(@post) do |f|post_form に変更したことに注意して下さい。

この例は、ローカル変数に渡すことが出来る、レンダリングヘルパーの別のオプションを示しています、
この場合では、パーシャル内のローカル変数 form に post_form オブジェクトを参照して欲しいです。

また、このフォームの上部に @post.tags.build を追加しましたが、
これは、ユーザーによって埋められたname を持っている新しいtagがあるのを確認するためです。
新しいタグを構築していないなら、作成する新しいTagオブジェクトが無いので、フォームは現れません。

今、 app/views/tags フォルダを作成し、tagのためのフォームを含む、_form.html.erb というファイルを作成しました。

<%= form.fields_for :tags do |tag_form| %>
  <div class="field">
    <%= tag_form.label :name, 'Tag:' %>
    <%= tag_form.text_field :name %>
  </div>
  <% unless tag_form.object.nil? || tag_form.object.new_record? %>
    <div class="field">
      <%= tag_form.label :_destroy, 'Remove:' %>
      <%= tag_form.check_box :_destroy %>
    </div>
  <% end %>
<% end %>

最後に、tagを表示するために、 app/views/posts/show.html.erb テンプレートを編集するでしょう。

<p class="notice"><%= notice %></p>

<p>
  <b>Name:</b>
  <%= @post.name %>
</p>

<p>
  <b>Title:</b>
  <%= @post.title %>
</p>

<p>
  <b>Content:</b>
  <%= @post.content %>
</p>

<p>
  <b>Tags:</b>
  <%= @post.tags.map { |t| t.name }.join(", ") %>
</p>

<h2>Comments</h2>
<%= render :partial => "comments/comment",
           :collection => @post.comments %>

<h2>Add a comment:</h2>
<%= render "comments/form" %>


<%= link_to 'Edit Post', edit_post_path(@post) %> |
<%= link_to 'Back to Posts', posts_path %> |
 

これらの変更により、同じビュー上で直接、投稿とそのタグを編集出来るでしょう。

しかしながら、メソッドが @post.tags.map { |t| t.name }.join(", ") を呼び出すのは厄介で、
ヘルパメソッドを作成することによって、これを処理できます。

12 ビューヘルパ(View Helpers)

ビューヘルパは、 app/helpers にあり、ビューのために再利用出来る小さなスニペットを提供します。
この場合、name 属性を使い、カンマを追加する、オブジェクトの塊を一纏めにするメソッドが欲しいです。
これはPost の show テンプレート用なので、PostsHelper内に置きます。

app/helpers/posts_helper.rb を開き、以下を追加して下さい:

module PostsHelper
  def join_tags(post)
    post.tags.map { |t| t.name }.join(", ")
  end
end

app/views/posts/show.html.erb 内のビューを以下のように編集できます:

<p class="notice"><%= notice %></p>

<p>
  <b>Name:</b>
  <%= @post.name %>
</p>

<p>
  <b>Title:</b>
  <%= @post.title %>
</p>

<p>
  <b>Content:</b>
  <%= @post.content %>
</p>

<p>
  <b>Tags:</b>
  <%= join_tags(@post) %>
</p>

<h2>Comments</h2>
<%= render :partial => "comments/comment",
           :collection => @post.comments %>

<h2>Add a comment:</h2>
<%= render "comments/form" %>


<%= link_to 'Edit Post', edit_post_path(@post) %> |
<%= link_to 'Back to Posts', posts_path %> | 

13 次は?(What’s Next?)

あなたの初めてのRailsアプリケーションを見た今、自身で自由に更新し実験出来ると感じてください。
しかし、助けを借りずにすべてを行う必要はありません。
Railsを始めるのに支援が必要なら、これらのサポートリソースを参照してください:

Railsはまた、付属の組み込みヘルプを、rake コマンドラインユーティリティを使用して生成することができます。:

  • rake doc:guides を実行すれば、アプリケーションの doc/guides にRails Guidesのフルコピーが出来ます。
    /oc/guides/index.htmlをブラウザで開けば、ガイドを探索できます。
  • rake doc:rails を実行すれば、アプリケーションの doc/api にRailsのAPI文書のフルコピーが出来ます。
    doc/api/index.htmlをブラウザで開けば、API文書を探索できます。~

14 設定の落とし穴(Configuration Gotchas)

Railsを動作させる最も簡単な方法は、全ての外部データをUTF-8として保存することです。
そうしなければ、RubyライブラリとRailsは、ネィティブなデータをUTF-8に変換できるでしょうが、
これは常に確実に動作するわけではなく、全ての外部データをUTF-8にするほうが確実に優れています。

この領域でミスを犯している場合、最も一般的な症状は、ブラウザ内に表示されている中に?マークと共に黒いダイヤモンドが出ることです。
もう一つの一般的な症状は、"u"と表示される代わりに"A?"のような文字が表示されます。
Railsは、これらの問題を自動的に修正、検出することができ、それらの一般的な原因を軽減するために内部の行数を取得します。
しかしながら、UTF-8として保存していない外部データがあると、
Railsによって、自動的に修正、検出することができない、この種の問題が時折発生するかもしれません。

データがUTF-8ではない、最も一般的な二つの情報源:

  • あなたのテキストエディタ:大半のテキストエディタ(Textmateのような)は、ファイルをデフォルトでUTF-8として保存します。
    あなたのテキストエディタがそうでないなら、ブラウザ内に?マークとともに、ダイヤモンドとして現れるテンプレート内の特殊文字の原因となるでしょう。
    これはまた、I18N翻訳ファイルにも適用されます。
    UTF-8がデフォルトで無い多くのエディタ(Dreamweaverのいくつかのバージョンのような)は、デフォルトをUTF-8に変更する方法が用意されているので、そうしましょう。
  • あなたのデータベース:Railsはデフォルトでデータベースからのデータを、境界上でUTF-8に変更します。
    しかしながら、あなたのデータベースが内部的にUTF-8を使っていない場合、ユーザーが入力した全ての文字を保存できません。
    例えば、データベースが内部でLatin-1を使っていて、ロシア語やヘブライ語、日本語の文字を入力したなら
    データはデータベースから永久に失われるでしょう。
    可能であれば、データベースの内部ストレージでUTF-8を使って下さい。

15 Changelog

Lighthouse ticket

  • July 12, 2010: Fixes, editing and updating of code samples by Jaime Iniesta
  • May 16, 2010: Added a section on configuration gotchas to address common encoding problems that people might have by Yehuda Katz
  • April 30, 2010: Fixes, editing and updating of code samples by Rohit Arondekar
  • April 25, 2010: Couple of more minor fixups Mikel Lindsaar
  • April 1, 2010: Fixed document to validate XHTML 1.0 Strict. Jaime Iniesta
  • February 8, 2010: Full re-write for Rails 3.0-beta, added helpers and before_filters, refactored code by Mikel Lindsaar
  • January 24, 2010: Re-write for Rails 3.0 by Mikel Lindsaar
  • July 18, 2009: Minor cleanup in anticipation of Rails 2.3.3 by Mike Gunderloy
  • February 1, 2009: Updated for Rails 2.3 by Mike Gunderloy
  • November 3, 2008: Formatting patch from Dave Rothlisberger
  • November 1, 2008: First approved version by Mike Gunderloy
  • October 16, 2008: Revised based on feedback from Pratik Naik by Mike Gunderloy (not yet approved for publication)
  • October 13, 2008: First complete draft by Mike Gunderloy (not yet approved for publication)
  • October 12, 2008: More detail, rearrangement, editing by Mike Gunderloy (not yet approved for publication)
  • September 8, 2008: initial version by James Miller (not yet approved for publication)

コメント欄(誤訳・誤字があれば教えて頂ければ幸いです。)

  • test -- akausagi 2010-09-18 (土) 06:28:12
  • 誤字レベルなのですが、3.1のwindowsでの開発は"less pleasant"なので"快適ではない"んだとおもいます 文脈的にも -- 2010-09-18 (土) 17:48:07


添付ファイル: filechallenge.png 4件 [詳細] fileposts_index.png 5件 [詳細] filerails_welcome.png 6件 [詳細]