|
Last-modified: 2010-09-18 (土) 17:48:08 (1h)
Getting Started with Rails †
原文 †http://guides.rubyonrails.org/getting_started.html Railsのはじめ方(Getting Started with Rails) †このガイドはRuby on Railsを立ち上げし、実行することまでを網羅してます。
このガイドはRails3.0に基づいています。 1 ガイドの仮定(Guide Assumptions) †このガイドは、Railsアプリをスクラッチから作りたい初心者向けです。
Ruby 1.8.7 p248 と p249には、Rails 3.0をクラッシュさせるマーシャリングのバグがあることに注意して下さい。 RailsはRubyプログラミング言語上で実行されるWebアプリケーションフレームワークです。 2 Railsとは?(What is Rails?) †RailsはRuby言語で書かれているウェブ開発フレームワークです。 Railsは自由なソフトウェアです。
2.1 MVCの設計(The MVC Architecture) †Railsはモデル、ビュー、コントローラ、普通はMVCと呼ばれるアーキテクチャで編成されています。
2.1.1 モデル 2.1.2 ビュー 2.1.3 コントローラー 2.2 Railsのコンポーネント(The Components of Rails) †Rails以下を含むWebアプリ作成のためのコンポーネントのフルスタックを提供します:
2.2.1 Action Pack 2.2.2 Action Controller 2.2.3 Action View 2.2.4 Action Dispatch 2.2.5 Action Mailer 2.2.6 Active Model 2.2.7 Active Record 2.2.8 Active Resource 2.2.9 Active Support 2.2.10 Railties 2.3 REST †RestはRepresentational State Transferの略で、RESTfulなアーキテクチャの基盤です。
例えば、Railsアプリで以下のようなリクエストは: DELETE /photos/17 IDが17のphotoのリソースを参照し、必要なアクション-リソースの削除-を示すと理解されるでしょう。 アーキテクチャのスタイルとしてRESTの詳細についてもっと知りたい場合、これらのリソースはフィールディングの論文よりも親しみやすいです:
3 新しいRailsプロジェクトの作成(Creating a New Rails Project) †このガイドを進めていくなら、(非常に)シンプルなウェブログである、 blog と呼ばれるRailsプロジェクトを作成しましょう。 3.1 Railsのインストール(Installing Rails) †ほとんどのケースでは、Railsをインストールする最も簡単な方法はRubyGemsを活用することです: 通常、rootユーザーとしてこれを実行します:
# gem install rails
Rails 3.0.0-betaでは、rubygemsのバグから、手動でRails自体の依存関係をインストールする必要があります。 Windows上で作業している場合は、Instant Railsのインストールが簡単に見えるでしょう。 3.2 ブログアプリケーションの作成(Creating the Blog Application) †このガイドを使用する最善の方法は、各ステップの順番通りに行い、 まず初めに、ターミナルを開き、ファイル作成権限があるフォルダに移動して、タイプします: $ rails new blog これはblogディレクトリ内にBlogという名前のRailsアプリケーションを作るでしょう。 rails -h を実行することで、Railsアプリケーションビルダが受け入れる全てのスイッチを見れます。 ブログのアプリを作成した後、作業を続けるため、直接そのフォルダに移動します: $ cd blog
いずれの場合でも、Railsは blog という名前のフォルダを作業ディレクトリ内に作成するでしょう。
3.3 必要なgemのインストール(Installing the Required Gems) †デフォルトではRailsアプリケーションは、Bundlerでgemの依存関係を管理します。 bundle install
3.4 データベースの設定(Configuring a Database) †データベースとやり取りするRailsアプリにだけついて。
3.4.1 SQLite3 データベースの設定 Railsには、軽量なサーバ不要のDBアプリであるSQLite3のサポートが付属しています。 development: adapter: sqlite3 database: db/development.sqlite3 pool: 5 timeout: 5000 設定なしに動くので、このガイド内ではデータストレージとしてSQLite3 データベースを使います。 3.4.2 MySQLデータベースの設定 用意済みのSQLite3データベースの代わりにMySQLを使う場合は、config/database.ymlがチョビっと違います。 development: adapter: mysql2 encoding: utf8 database: blog_development pool: 5 username: root password: socket: /tmp/mysql.sock 開発用コンピュータのMySQLのインストールが、空のパスワードのrootユーザーを含んでいたなら、この設定で動くでしょう。 3.4.3 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が多くのことに使用する汎用コマンドランナーです。 4 Hello, Rails! †伝統的な新しい言語を開始地点の1つは、さっと画面上にいくつかのテキストを表示することで、 4.1 Webサーバーを立ち上げよう(Starting up the Web Server) †実際には、機能的なRailsのアプリケーションをあなたはすでに持っています。 $ rails server これはデフォルトで、MongrelのWebサーバーのインスタンスを起動します。(他のWebサーバーも使用することができます) Webサーバーを停止するには、サーバーが走っているターミナルでCtrl+Cを押してください。 "Welcome aboard"ページは、新しいRailsアプリケーションのためのスモークテストです: 4.2 Rails君、"Hello"と言って(Say “Hello”, Rails) †Railsに"Hello"と言わせるには、最低でも、コントローラとビューを作成する必要があります。 $ rails generate controller home index Windows上の場合や、非標準的な方法でRubyをセットアップした場合は、 Railsは、 app/views/home/index.html.erb を含むいくつかのファイルを作成するでしょう。 <h1>Hello, Rails!</h1> 4.3 アプリケーションのHomeの設定(Setting the Application Home Page) †今ではコントローラーとビューを作成しました、"Hello Rails"を見たい時、Railsに伝える必要があります。 これを実行する最初の手順は、アプリケーションのデフォルトのページを削除することです: $ rm public/index.html Railsが、コントローラーから生成した動的なページよりも、 さて、実際のホームがどこに位置するかをRailsに教えてあげる必要があります。 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 は、アプリケーションの主要ないくつか部分を生成するための素早い方法です。 6 リソースを作成します。(Creating a Resource) †blogアプリケーションの場合、scaffoldされたPostリソースを生成するとこから始められます。:これは、単一のブログの投稿を表します $ rails generate scaffold Post name:string title:string content:text scaffoldingでササッと組み上げて動かせますが、生成された"全てにフィットする何か"のコードが、アプリケーションに完璧にフィットすることはありそうもないです。 scaffoldドジェネレータはフォルダにそって、アプリケーション内に15のファイルを構築し、更に1つを編集します。
6.1 マイグレーションの実行(Running a Migration) †rails generate scaffoldコマンドで生成されるものの一つに、データベースのマイグレーションがあります。 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、 この時点で、マイグレーションを実行するための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を動かし始める準備が整いました。 これはRailsがpostsのindexビューをRailsがレンダリングした結果です。 developmentモード(これはあなたがデフォルトで作業している)は、ブラウザのリクエストごとにRailsがアプリケーションの 6.4 モデル(The Model) †モデルファイルである app/models/post.rb は、これでわかるぐらい、単純です。: class Post < ActiveRecord::Base end このファイルは大きくありません。-しかし、 Post クラスが ActiveRecord::Base を継承していることは注意しておいてください。 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文字の長さであることを確認するでしょう。 6.6 コンソールの使用(Using the Console) †アクション内のバリデーションを見てみるには、コンソールを使用することができます。 $ 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のインスタンスの作成し、それを保存しようとし、 終わったら、 exit とタイプして return を押して、コンソールを抜けて下さい。 development Webサーバーとは異なり、コンソールは自動的にそれぞれの行のコードを新たにロードしません。 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のレコードを見つけることの詳細については、 respond_to ブロックは、このアクションを呼び出すHTMLとXMLの両方を処理します。~ http://localhost:3000/posts.xmlをブラウズすれば、XML形式ですべてのpostが表示されるでしょう。 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配列の内容を反復処理します。
Railsの以前のバージョンでは、ページに挿入される前に、どんなHTMLもエスケープされるために レンダリングプロセスの詳細については、Layouts and Rendering in Railsを参照してください。 6.8 レイアウトのカスタマイズ(Customizing the Layout) †ビューは、HTMLがWebブラウザにどうやって表示されるのかという話の一部に過ぎません。 app/views/layouts/posts.html.erb のような、コントローラー固有のレイアウトを作っていました。~ しかしながら、Rails3.0ではこれは変更されました。 <!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つのアクションを含みます。 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内のパーシャルのための最初の導入です。 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 %> このパーシャルは、呼ばれたビューファイル内で定義された全てのインスタンス変数を受け取ります。 パーシャルの他の情報は、Layouts and Rendering in Railsガイドを参照して下さい。 form_for ブロックは、HTMLフォームを作成するために使用されます。~ このブロック内では、フォーム上のさまざまなコントロールを作成するためのメソッドにアクセスしています。 form_for ブロックはまた、新しい投稿や投稿の編集をするなら、充分うまくやるぐらい賢く、~ HTML出力内で適切に、フォームのactionタグと送信ボタンの名前を設定します。 モデルに関連付けられていない任意のフィールドを表示するためにHTMLフォームを作成する必要があるなら、 ユーザーがこのフォーム上のCreate Postボタンをクリックする時、ブラウザはコントローラの 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 の場合、ユーザーは実際に、投稿作成プロセス中にどんなページがレンダリングされるところも、見ることは無いでしょう。~ Railsはレコードを保存してすぐに、新しい投稿にリダイレクトされるからです。 6.10 個々の投稿を表示(Showing an Individual Post) †index ページの、ある投稿のshowリンクをクリックした時に、http://localhost:3000/posts/1のようなURLへ運ばれます。~ Railsはこれを、そのリソースのための show アクションの呼び出しだと認識し、:idパラメータとして1を渡します。 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 を使用します。 <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つのプロセスです。 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パーシャルを使い、 このビューで作られたフォームの送信は、コントローラー内の 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ビューにリダイレクトされます。 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 メソッドは、データベースから対応するレコードを削除します。 7 二番目のモデルを追加する(Adding a Second Model) †今、scaffoldで構築されたモデルにどのようなものか見てきました、アプリケーションに2番目のモデルを追加する時が来ました。 7.1 モデルの生成(Generating a Model) †Railsのモデルは単数形の名前を使用し、対応するデータベースのテーブルには複数形の名前を使用します。 $ rails generate model Comment commenter:string body:text post:references このコマンドは、4つのファイルが生成するでしょう:
まず、comment.rbを見てみましょう: class Comment < ActiveRecord::Base belongs_to :post end これは以前に見たpost.rbモデルに非常に似ています。 モデルに加えて、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つのモデル間の関係を簡単に宣言することができます。
実際には、これは、Railsがこのアソシエーションを宣言するために使用する構文に非常に近いものです。 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つの宣言は、自動的な動作をいい具合に有効にします。 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つの空のディレクトリを作成します:
他のブログと同様、読者は投稿を読んだあとに、直接コメントを作り、コメントを追加し、 そこでまず、新しいコメントを作成するために、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ページ上に、新しいコメントを作成するフォームを追加します。 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_path(@post) ヘルパを使い、元のpostに送り返します。 <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のセクションを取り除きましょう、 <%= 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 を定義します。 app/views/comments ディレクトリ内の _form.html.erb ファイルをレンダリングしたいことを理解するのに充分なぐらい賢いです。~ @post オブジェクトは、インスタンス変数として定義しているので、ビュー内でレンダリングされたパーシャルで、利用可能です。 9 コメントの削除(Deleting Comments) †ブログのもう一つの重要な機能は、スパムコメントを削除できることです。 最初に、 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 に発行するでしょう、 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を検索し、 9.1 関連づいたオブジェクトの削除(Deleting Associated Objects) †ある投稿を削除したいなら、それと関連しているコメントもまた削除する必要があります。 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認証システムを提供しています。 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 明示的に、ユーザー名とパスワードを好きなものに変更することができます。 認証されていない場合、 PostsController内で、様々なアクションへのアクセスをブロックする方法を持つことが必要で before filterを使うために、PostsController の上部にそれを指定します。 class PostsController < ApplicationController before_filter :authenticate, :except => [:index, :show] # GET /posts # GET /posts.xml def index @posts = Post.all respond_to do |format| # 簡潔のためのスニペット また、認証されたユーザーのみがコメントを削除することを許可したいので、 class CommentsController < ApplicationController before_filter :authenticate, :only => :destroy def create @post = Post.find(params[:post_id]) # 簡潔のためのスニペット 今、新しい投稿を作成しようとしたら、BASIC HTTP認証チャレンジで挨拶されるでしょう: 11 色々なモデルのフォームを組み立てる(Building a Multi-Model Form) †あなたの平均的なブログの他の機能は、投稿にタグを設定する機能です。 これを実証するために、作成した投稿の右に、それぞれの投稿に複数のタグを与えるためのサポートを追加しましょう。 $ rails generate model tag name:string post:references 再度、データベーステーブルを作成するためにマイグレーションを実行します: $ rake db:migrate 次に、アソシエーションの逆側を作成するために post.rb を編集し、 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"チェックボックスの表示をすぐに構築できるように伝えます。 <% @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 に変更したことに注意して下さい。 この例は、ローカル変数に渡すことが出来る、レンダリングヘルパーの別のオプションを示しています、 また、このフォームの上部に @post.tags.build を追加しましたが、 今、 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 にあり、ビューのために再利用出来る小さなスニペットを提供します。 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はまた、付属の組み込みヘルプを、rake コマンドラインユーティリティを使用して生成することができます。:
14 設定の落とし穴(Configuration Gotchas) †Railsを動作させる最も簡単な方法は、全ての外部データをUTF-8として保存することです。 この領域でミスを犯している場合、最も一般的な症状は、ブラウザ内に表示されている中に?マークと共に黒いダイヤモンドが出ることです。 データがUTF-8ではない、最も一般的な二つの情報源:
15 Changelog †
コメント欄(誤訳・誤字があれば教えて頂ければ幸いです。) †
|