show()アクションメソッド内の冒頭で実行している以下の部分でCategoryクラス(scaffoldで生成されたapp/models/category.rb)の、クラスメソッドfind()呼び出しています。
@category = Category.find(params[:id])
Categoryクラスの内容は、次のように非常にシンプルです。
class Category < ActiveRecord::Base end
CategoryクラスはActiveRecord::Baseクラスを継承しています。ActiveRecordは、O/Rマッピングツールの1つで、設定ファイルを記述しなくとも、クラス名とテーブル名の命名から自動的にマッピングができるのが大きな特徴の1つです(Railsのコンセプト「設定よりも規約」の一例)。
今回は、クラス名「Category」とテーブル名の「categories」が自動的に対応付けらます。
ActiveRecordのfind()メソッドは、categoriesテーブルに対してSELECT文を発行し、結果をCategoryクラスのインスタンスにマッピングして返すメソッドです。
paramsは、ApplicationControllerが提供する、リクエストパラメータを受け取るためのメソッド(参考の「Parameters」の章)です。params[:id]の部分で、以下の【ID】に指定された値を受け取ることができます。
http://【Railsをインストールしたマシンのアドレス】:3000/categories/【ID】
このIDを指定してfind()を呼び出すと、合致するidを持つレコードが検索され、そのレコードの内容がセットされたCategoryクラスのインスタンスが戻り値として取得できます。ActiveRecordは、マッピングされたテーブルのカラム名を取得し、Categoryクラスに対して、以下のようなカラムの値の取得や、値の設定の手段を簡単に行うインターフェイスを提供してくれます。
@category.name @category.description = "..."
これを通じて検索結果を簡単に取得したり、またデータを簡単に更新したりできる仕組みになっています。ActiveRecordの詳細に興味があるなら、「Class: ActiveRecord::Base」を参照してください。
コントローラーのコードをもう一度見てみましょう。
@category = Category.find(params[:id])
「@変数名」という記述は、Rubyではクラスのインスタンス変数を表します(参考)。
コントローラーのメンバ変数に代入されたものは、ビューでも利用できる仕組みになっていますので、コントローラーからビューへ、変数の受け渡しに利用できます(参考「 ActionController::Base」の「Renders」の章)。
次に、下記コードを見てみましょう。
respond_to do |format| format.html # show.html.erb format.xml { render :xml => @category } end
このrespond_to()メソッドでは、ビューの呼び出し方を指定しています。
先ほど、「このアクションメソッドは、以下の両方でアクセスされる」と説明しました。
Railsでは、URLに拡張子「xml」が付いた場合は、クライアントはXML形式のレスポンスを期待していると解釈して、XML用のレスポンスを用意しようとします。特に拡張子が付かなければHTMLが返されます。
このようにRailsは、同じアクションメソッド内で、Webブラウザだけでなく、Web APIクライアントなどにも簡単に応答できる仕組みを提供しています(「同じことを繰り返さない」の一例)。この仕組みは後編で、RJS対応をする際に利用します。Railsのrespond_toの仕組みの詳細に興味があるならこちらを参照してください。
CategoriesControllerのshow()アクションメソッドのHTMLレスポンスに対応するテンプレートファイルは、scaffoldで生成された次のファイルです。
app/views/categories/show.html.erb コントローラー名 アクションメソッド名 レスポンス形式 |
<p> <b>Name:</b> <%=h @category.name %> </p> <p> <b>Description:</b> <%=h @category.description %> </p> <%= link_to 'Edit', edit_category_path(@category) %> | <%= link_to 'Back', categories_path %>
このテンプレートはPHPの<?php ?>などと同様に、「<%= …… %>」の中に、Rubyコードを記述できる書式になっており、ユーザーにはRubyコードの実行結果に置き換えられたものが返される仕組みになっています。
変数「@category」は、 CategoriesControllerの「@category = Category.find(params[:id])」でセットした@categoryと同一オブジェクトです。
Railsのerbの仕組みの詳細に興味があるなら、以下を参照してください。
Railsにはビュー内でよく使われる記述(HTMLタグなど)の生成をしてくれるヘルパメソッドと呼ばれるメソッド群があります。以下のように、show.html.erbで利用されていたlink_to()もヘルパメソッドです(参考)。
<%= link_to 'Edit', edit_category_path(@category) %>
link_toはタグを生成するもので、次のようなHTMLタグが生成されます。
<a href="/categories/523709510/edit">Edit</a>
edit_category_pathは、RailsのREST対応で自動的に生成されたヘルパメソッドで、渡された引数「@category」に対応したカテゴリ詳細画面のURLを返すメソッドです。
ヘルパメソッドの詳細に興味があるなら、「Module: ActionController::Helpers::ClassMethods」を参照してください。
ここからは、scaffoldで生成されたひな型を修正していきます。
サンプルでは、カテゴリ詳細画面の上部にカテゴリ名一覧が表示されているので、これが表示されるように修正してみます。次の流れになります。
1を実現するには、またActiveRecordのfind()メソッドを使用します。CategoriesControllerクラスのshow()アクションメソッド内に、次の1行を追加しました。
def show @categories = Category.find(:all) // この行を追加 @category = Category.find(params[:id])
「Category.find(:all) 」は、categoriesテーブルの全レコードを取得し、Categoryクラスのインスタンスの配列として返します(参考)。
ビューで全カテゴリのデータを描画するために、今回はRailsの部分テンプレートの仕組み「パーシャル」を使います。「app/views/categories/show.html.erb」の先頭に次の記述を追加しました。
<ul id='categories'> <%= render({:partial => "category", :collection => @categories}) %> </ul>
このrender()メソッドは、部分テンプレートcategoryで、「@categories内のCategoryインスタンスそれぞれを使って繰り返し描画を行う」という意味です(参考)。
今回の部分テンプレート名は「category」としました。部分テンプレートファイルとして、以下のように、部分テンプレート名に「_」(アンダーバー)を付けたファイル名で用意します。
部分テンプレート内では、「category」という変数で、現在描画を行っているカテゴリにアクセスできます。部分テンプレートの内容を次のようにしました。
<li><%= link_to(category.name, category_path(category)) %></li>
category_pathは、RailのREST対応で自動的に生成されたヘルパメソッドで、渡された引数のCategoryインスタンスに対応したカテゴリ詳細画面のURLを返すメソッドです(参考)。
画面を確認してみましょう。
カテゴリ詳細画面の上部にカテゴリ名一覧が表示され、クリックすると、そのカテゴリ詳細画面に遷移するようになりました。
今回はRuby on RailsのRJSを使用したAjaxの開発を理解する足掛かりとして、Ruby on Railsそのものの解説をしてきました。Railsは開発手法が細かく規定されており、これに沿って開発することで非常に高い生産性を実現します。
今回は、たくさんのRails流のルールを知る必要があったため、RJSの解説まで至ることができませんでしたが、次回はRJSの開発をメインに行っていきますので、どうぞお楽しみに!
Copyright © ITmedia, Inc. All Rights Reserved.