レシピをカテゴリー分けする
これでレシピとカテゴリーをもったクックブックになった。あとは紐付けが必要だ。レシピがなんらかのカテゴリーに所属するようにしたい。これはrecipesテーブルにフィールドを追加してそれぞれのレシピのカテゴリーid
を持たせて実現しよう。あとはカテゴリーのドロップダウンリストを使えるようにするためにレシピにedit
メソッドを追加しよう。
まず、category
テーブルのキーと対応するようにint(6)
のcategory_id
フィールドをrecipe
テーブルへ追加する。Figure 48の通り。
Figure 48. 新しいcategory_id
を持ったrecipe
テーブル
このフィールドにはレシピの所属するカテゴリーのid
が入る。ここでRecipe
モデルクラスにもこのことを教えてやろう。
c:\rails\cookbook\app\models\recipe.rb とc:\rails\cookbook\app\models\category.rb を開いて、Figures 49 ,50のように各モデルクラスに一行追加する。
Figure 49. Recipe
モデルにリレーションシップを設定
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
メソッドを追加しよう。
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,"にしよう。
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のように見えるだろうか。
Figure 53. カテゴリーと共に表示されたレシピ一覧
読者のための次のステップ
おめでとう。これであなたもRailsアプリケーションを組み上げることができた。もちろん、まだまだ足りないところはある。それでもこれはちゃんと動く。
あなたのための宿題をいくつか。
- レシピを削除することができない。editテンプレートに削除ボタン(かリンク)を追加してみよう。
- レシピ一覧のページにカテゴリー編集のページへのリンクがない。どうにかしてほしい。
- 特定のカテゴリーのレシピだけを表示するようなことができると便利だ。例えば、snackのレシピだけを全部表示させたいことがあるだろうし、あるいはbeverageのレシピだけを全部一覧したいこともあるだろう。レシピ一覧のページに各カテゴリーの名前を並べて、そのカテゴリーの全レシピだけを表示するページへのリンクにしてほしい。
この記事は二つのパートに分かれており、こちらはその一つ目のパートになる。二つ目のパートでは上の項目を実装していくのだが、あなたがそれをじっと待っている必要はない。これらを自分で実装してみるのはRailsでの開発のとてもいい第一歩になると思う。
Parting Thoughts
Ruby on RailsはWebアプリケーションの開発をまったく新しい次元に押し上げた。Railsが肩代わりしてくれるので、あなたはもうこれまでのうんざりするような作業をしなくて済むようになった。もしRailsの命名規約に従わないようなレガシーデータベースを使わないといけなくても、Railsを使うことによる生産性の向上を諦めないといけないわけじゃない。どのテーブル名とカラム名を使えればいいかをRailsに明示する方法も残されている。
さぁ、これでどれだけ手軽にWebアプリケーションが作れるかの触りを見てもらったし、もう他のやり方でやろうとは思わないんじゃないかな。
たぶんあなたの雇い主は特定のフレームワークやプログラミング言語をあなたに強いてきたと思う。あなたにはまだ数日の猶予があるんだから、Railsでプロトタイプを作ってボスに言ってやろう。「アプリケーションの全体をRuby on Rails使って作っちゃいました。もしお望みなら、我々にはあと数ヶ月残されています。当初の予定どおりのものに仕上げることもできますよ。」(ニンマリ)
資料集
Webサイト
- Ruby公式ホームページ
- Ruby on Rails公式ホームページ
- Rubyを学ぶ一番のやり方: Programming Ruby を読もう。
- オープンソースのRuby関連プロジェクトの代表的なホームページ: RubyForge
メーリングリスト
Curt Hibbs は30年以上の経験の中で数えきれないほどのプラットフォーム、プログラミング言語、テクノロジーを股にかけてきたSaint Louis, Missouriに住むシニアソフトウェアデベロッパーである。