タブがアクティブかどうかのデザインを変更
次に、カテゴリ切り替えのタブを、現在表示しているカテゴリがアクティブになるように変更します。例えば、「動物Tシャツ」カテゴリがアクティブな場合は、次のようなマークアップになるようにします。
*** 一部省略されたコンテンツがあります。PC版でご覧ください。 ***
タブはパーシャルで実現されているので、パーシャルに現在アクティブなカテゴリのCategoryインスタンスを渡し、パーシャル内で、現在描画中のカテゴリがアクティブかどうかを判定して描画し分けるようにします。
タブがアクティブかどうかの判定
localsオプションにハッシュを指定すると、パーシャル内で指定した変数が参照できます(参考:renderメソッドのリファレンス)。
*** 一部省略されたコンテンツがあります。PC版でご覧ください。 ***
パーシャル内では、下記のようにactive_category変数と、現在描画中のカテゴリを比較しアクティブかどうかを判定します。
*** 一部省略されたコンテンツがあります。PC版でご覧ください。 ***
ここで決定したclass_valueで、<li>を描画します。
*** 一部省略されたコンテンツがあります。PC版でご覧ください。 ***
これで、アクティブなタブを表現できました。
RJSでアクティブなタブを切り替える
次に、RJSでタブの<li>のclassも変更できるようにして、アクティブなタブもRJSで切り替えるようにします。
まず、<li>に「category_現在のID」という値で、idを付けて、RJSで<li>タグの操作が行えるようにしました。
*** 一部省略されたコンテンツがあります。PC版でご覧ください。 ***
次に、RJSに次の記述を追加して、タブがクリックされたら、一度すべてのタブを非アクティブにします。
*** 一部省略されたコンテンツがあります。PC版でご覧ください。 ***
その後、現在のカテゴリのみをアクティブにします。
*** 一部省略されたコンテンツがあります。PC版でご覧ください。 ***
selectは、CSSパターンを引数で受け取り、検索された要素に対して処理をすることができるメソッドです(参考:selectのリファレンス)。selectの結果に対してブロック付きでeachを呼び出していますが、これがprototype.jsのeachを無名関数で呼び出す記述に書き換わります(参考:prototype.jsのeachのリファレンス:)。
これはRJSのコレクションプロキシという機能です(参考:RJS Element and Collection Proxies)。結果的に、次のJavaScriptが生成されます。
*** 一部省略されたコンテンツがあります。PC版でご覧ください。 ***
これで、RJSでもアクティブなタブを表現できました。
データベースの商品情報をscaffoldで作成し、表示させる
ここからは、カテゴリ内商品を表示できるようにしていきます。次の手順で説明していきます。
- scaffoldによる商品の作成
- テーブル間のリレーションの設定
- モデル間のリレーションの設定
- 商品のサンプルデータの登録
- カテゴリ詳細画面内に商品一覧を埋め込み
scaffoldによる商品の作成とカテゴリとの関連の設定
カテゴリのときと同様に、scaffoldで商品の一覧表示や追加、修正、削除などができるようにしてから、カテゴリ詳細画面で商品一覧を呼び出すようにします。商品(product)は、商品名(name)や画像のURL(image_url)、価格(price)の情報を持つことにします。次のようにscaffoldを実行しました。
*** 一部省略されたコンテンツがあります。PC版でご覧ください。 ***
テーブル間のリレーションの設定
次にマイグレーションを使って、カテゴリのときと同様にデータベース上にテーブルを作成します。カテゴリと商品には、「1つのカテゴリに複数の商品が登録される」という1対多のリレーションがあります。このため、データベースのproductsテーブル上に、categoriesテーブルのidカラムへの外部キー参照が必要です。
productsテーブルに外部キー参照を追加するために、「db:migrate」のrakeタスクを実行する前に、scaffoldで生成された「db/migrate/20080929023746_create_products.rb」に次の行を追加します(参考:refencesのリファレンス)。
*** 一部省略されたコンテンツがあります。PC版でご覧ください。 ***
追加したら「db:migrate」を実行します。
*** 一部省略されたコンテンツがあります。PC版でご覧ください。 ***
生成されたproductsテーブルの構造を、sqliteコマンドを使って確認しましょう。
*** 一部省略されたコンテンツがあります。PC版でご覧ください。 ***
「category_id」というカラムが存在します。これで、カテゴリテーブルと商品テーブルのリレーションの設定はできました。
モデル間のリレーションの設定
次に、ActiveRecordの「アソシエーション」という機能を使用し、モデルクラス間のリレーションを設定します。CategoryクラスとProductクラスに、次の記述を追加します。
*** 一部省略されたコンテンツがあります。PC版でご覧ください。 ***
アソシエーションを設定すると、そのモデルクラスに、関連付けられたモデルを簡単に処理するためのメソッドが追加され、プログラミングがより楽になります。
- Categoryクラスに「has_many :products」を設定することで追加されるメソッドの例(参考:has_manyのリファレンス)
- category.products
そのカテゴリに所属する商品を配列として返す - category.products << another_product
そのカテゴリに所属する商品を新しく追加する
- category.products
- Productクラスに「belongs_to :category」を設定することで追加されるメソッドの例 (参考:belongs_toのリファレンス)
- product.category
その商品が属するカテゴリを返す - product.category = another_category
その商品が属するカテゴリを設定する
- product.category
YAML形式で商品のサンプルデータを登録
次に、カテゴリのときと同様に、商品のサンプルデータをtest/fixtures/products.yml内にYAML形式で記述します。商品はカテゴリに所属するので、次のようにサンプルデータ上で所属するカテゴリ情報を指定します。
*** 一部省略されたコンテンツがあります。PC版でご覧ください。 ***
「category」のカラムに指定している「animal」は、前回記事でカテゴリのサンプルデータを登録する際に指定していたレコードの識別名です。
*** 一部省略されたコンテンツがあります。PC版でご覧ください。 ***
このように、リレーションの関係にあるレコードを識別名で指定できる機能はFoxy Fixturesなどと呼ばれています。products.ymlを作成したら、rakeタスク「db:fixtures:load」を実行して、サンプルデータを登録します。
*** 一部省略されたコンテンツがあります。PC版でご覧ください。 ***
商品「ふくろう」とひも付けられたカテゴリの情報を確認してみましょう。
*** 一部省略されたコンテンツがあります。PC版でご覧ください。 ***
これで、商品とカテゴリをひも付けながら商品を登録できました。scaffoldが生成される商品一覧画面を見てみましょう。
Copyright © ITmedia, Inc. All Rights Reserved.