Rolling on Ruby on Rails - Japanese Translation - p5

by tanabe on October 06, 2005

Pages: 1, 2, 3, 4, 5

レシピをカテゴリー分けする

これでレシピとカテゴリーをもったクックブックになった。あとは紐付けが必要だ。レシピがなんらかのカテゴリーに所属するようにしたい。これはrecipesテーブルにフィールドを追加してそれぞれのレシピのカテゴリーidを持たせて実現しよう。あとはカテゴリーのドロップダウンリストを使えるようにするためにレシピにedit メソッドを追加しよう。

まず、categoryテーブルのキーと対応するようにint(6)category_id フィールドをrecipe テーブルへ追加する。Figure 48の通り。

the recipe table with its new category_id
Figure 48. 新しいcategory_idを持ったrecipe テーブル

このフィールドにはレシピの所属するカテゴリーのid が入る。ここでRecipe モデルクラスにもこのことを教えてやろう。

c:\rails\cookbook\app\models\recipe.rbc:\rails\cookbook\app\models\category.rb を開いて、Figures 49 ,50のように各モデルクラスに一行追加する。

setting relationships in the Recipe model
Figure 49. Recipe モデルにリレーションシップを設定

setting relationships in the
Category model
Figure 50. Category モデルにリレーションシップを設定

これでRailsに、レシピは一つのカテゴリーに所属することと一つのカテゴリーは複数のレシピを持てることが伝えられるのがわかるだろう。実際にRubyのコード上でも、これらの宣言(has_manyやbelongs_to)がデータ同士のリレーションシップを表現するメソッドを生成する。

例えば@recipeとしてレシピオブジェクトがあったとすると、カテゴリー名を得るためには@recipe.category.nameというコードがあればいい。同じように@categoryというカテゴリーオブジェクトがあったなら、このカテゴリーに属するすべてのレシピのコレクションを使いたいときは@category.recipesと書けばいい。

さて、そろそろレシピをカテゴリーに分類するためのレシピのedit処理とテンプレート(template from the scaffolding)の仕上げに入ろう。c:\rails\cookbook\app\controllers\recipe_controller.rb を開いたら、Figure 51のようにeditメソッドを追加しよう。

the Recipe controller's new edit method
Figure 51. Recipe コントローラーの新しいedit メソッド

このメソッドはテンプレートがレシピの編集("edit recipe")ページを作成するときに使われる二つのインスタンス変数を作成している。@recipeはぼくらが編集したいレシピだ(idパラメータはウェブリクエストから渡される)。@categoriesはデータベース中のすべてのカテゴリーのコレクションだ。テンプレートがカテゴリー選択のドロップダウンリストを作成するのに使われる。

c:\rails\cookbook\app\views\recipe の中にedit.rhtml という名前のファイルを作成して、下記のようなHTMLのテンプレートを記入しよう。下のコードはほとんどは普通のHTMLで、カテゴリー選択のドロップダウンリストを作成するために<select> タグと<option> タグが仕掛けられている。

<html>
 <head>
  <title>Edit Recipe</title>
 </head>
 <body>
 <h1>Edit Recipe</h1>

 <form action="../update/<%= @recipe.id %>" method="POST"">
  <input id="recipe_id" name="recipe[id]" size="30" 
         type="hidden" value="<%= @recipe.id %>" />
  <p><b>Title</b><br>
  <input id="recipe_title" name="recipe[title]" size="30" 
         type="text" value="<%= @recipe.title %>" />
  </p>
  <p><b>Description</b><br>
  <input id="recipe_description" name="recipe[description]" 
         size="30" type="text" 
         value="<%= @recipe.description %>" />
  </p>
  <p><b>Category:</b><br>

  <select name="recipe[category_id]">
   <% @categories.each do |category| %>
       <option value="<%= category.id %>" 
         <%= ' selected' if category.id == @recipe.category_id %>>
         <%= category.name %>
       </option>
   <% end %>
  </select></p>

  <p><b>Instructions</b><br>
  <textarea cols="40" id="recipe_instructions" 
            name="recipe[instructions]" 
            rows="20" wrap="virtual">
    <%= @recipe.instructions %>
  </textarea> </p>
  <input type="submit" value="Update" />
 </form>

 <a href="/recipe/show/<%= @recipe.id %>">
   Show
 </a> | 
  <a href="/recipe/list">
  Back 
 </a>

 </body>
</html>

@recipe@categories の変数が使われているのが確認できる。選択リストを作るためにすべてのカテゴリーをループさせている所に注目してほしい。<option> タグを見て、編集中のレシピが属するカテゴリーが選択された状態にするためにタグがどのように使われているかを理解してほしい。テンプレートをよく見て、試してみてほしい。

ブラウザでhttp://127.0.0.1:3000/recipe/list を開き、レシピ"Ice Water"を編集しよう。Figure 52のようにカテゴリーを"Beverages,"にしよう。

changing the category for a recipe
Figure 52. レシピのカテゴリーを変更する

最後のステップへ行く前に、データベース上のすべてのレシピがカテゴリーを持っていることを確認してほしい。それぞれを編集(Edit)し、カテゴリーを選択して、更新しよう。これが漏れていると、次のステップでエラーになる。

レシピ一覧にカテゴリーを表示させる

これが最後のステップだ。さっき作ったlistのテンプレートをいじって、それぞれのレシピのカテゴリーが表示されるようにしよう。

c:\rails\cookbook\app\views\recipe\list.rhtml を編集して、以下のようにする。

<html>
<head>
<title>All Recipes</title>
</head>
<body>

<h1>Online Cookbook - All Recipes</h1>
<table border="1">
 <tr>
  <td width="40%"><p align="center"><i><b>Recipe</b></i></td>
  <td width="20%"><p align="center"><i><b>Category</b></i></td>
  <td width="20%"><p align="center"><i><b>Date</b></i></td>
 </tr>

 <% @recipes.each do |recipe| %>
  <tr>
   <td><%= link_to recipe.title, :action => "show", :id => recipe.id %></td>
   <td><%= recipe.category.name %></td>
   <td><%= recipe.date %></td>
  </tr>
 <% end %>
</table>
<p><%= link_to "Create new recipe", :action => "new" %></p>

</body>
</html>

http://127.0.0.1:3000/recipe/list をブラウズして確認してみよう。Figure 53のように見えるだろうか。

recipes listed with categories
Figure 53. カテゴリーと共に表示されたレシピ一覧

読者のための次のステップ

おめでとう。これであなたもRailsアプリケーションを組み上げることができた。もちろん、まだまだ足りないところはある。それでもこれはちゃんと動く。

あなたのための宿題をいくつか。

  • レシピを削除することができない。editテンプレートに削除ボタン(かリンク)を追加してみよう。
  • レシピ一覧のページにカテゴリー編集のページへのリンクがない。どうにかしてほしい。
  • 特定のカテゴリーのレシピだけを表示するようなことができると便利だ。例えば、snackのレシピだけを全部表示させたいことがあるだろうし、あるいはbeverageのレシピだけを全部一覧したいこともあるだろう。レシピ一覧のページに各カテゴリーの名前を並べて、そのカテゴリーの全レシピだけを表示するページへのリンクにしてほしい。

この記事は二つのパートに分かれており、こちらはその一つ目のパートになる。二つ目のパートでは上の項目を実装していくのだが、あなたがそれをじっと待っている必要はない。これらを自分で実装してみるのはRailsでの開発のとてもいい第一歩になると思う。

Parting Thoughts

Ruby on RailsはWebアプリケーションの開発をまったく新しい次元に押し上げた。Railsが肩代わりしてくれるので、あなたはもうこれまでのうんざりするような作業をしなくて済むようになった。もしRailsの命名規約に従わないようなレガシーデータベースを使わないといけなくても、Railsを使うことによる生産性の向上を諦めないといけないわけじゃない。どのテーブル名とカラム名を使えればいいかをRailsに明示する方法も残されている。

さぁ、これでどれだけ手軽にWebアプリケーションが作れるかの触りを見てもらったし、もう他のやり方でやろうとは思わないんじゃないかな。

たぶんあなたの雇い主は特定のフレームワークやプログラミング言語をあなたに強いてきたと思う。あなたにはまだ数日の猶予があるんだから、Railsでプロトタイプを作ってボスに言ってやろう。「アプリケーションの全体をRuby on Rails使って作っちゃいました。もしお望みなら、我々にはあと数ヶ月残されています。当初の予定どおりのものに仕上げることもできますよ。」(ニンマリ)

資料集

Webサイト

メーリングリスト

Curt Hibbs は30年以上の経験の中で数えきれないほどのプラットフォーム、プログラミング言語、テクノロジーを股にかけてきたSaint Louis, Missouriに住むシニアソフトウェアデベロッパーである。




この記事へのトラックバック
Rolling with Ruby on Rails MySQL環境での開発サン...
Panther で Ruby on Rails (3)【花染人和クリエイション::MACなDTPと開発::トラブル記録】at October 17, 2006 23:20
Rolling with Ruby on Rails MySQL環境での開発サン...
Panther で Ruby on Rails (3)【花染人和クリエイション::MACなDTPと開発::トラブル記録】at October 17, 2006 23:22
Rolling with Ruby on Rails MySQL環境での開発サン...
Panther で Ruby on Rails (3)【花染人和クリエイション::MACなDTPと開発::トラブル記録】at October 17, 2006 23:39
この記事へのコメント
はじめまして。英語があまり得意でないのでこういうページがあると非常に助かります。ところでedit.rhtmlのコードをそのままコピー&ペーストしたところ、エラーが出て動きませんでした。それで原文の方にあたってみたら、edit.rhtmlのコードが変わっていました。そちらを使用するとちゃんと動きました。お時間があるときにでも、修正しておいて頂けると、自分みたいにはまる人も少なくなると思います。よろしくお願いします。
ONLamp.com: Rolling with Ruby on Rails
http://www.onlamp.com/pub/a/onlamp/2005/01/20/rails.html?page=5

Posted by 匿名希望 at October 10, 2005 20:54
>匿名希望さん

ご指摘ありがとうございました。
早速修正いたしました。
私の力不足の部分が大いにあり、こうしてご指摘頂けるのがなにより有難いです。
Posted by tanabe at October 11, 2005 02:49