Rails モデル間の関係の構築
執筆: Brian Leonard、管理: Gail Chappell
2007 年 12 月 [リビジョン番号: V6.0--3]
このチュートリアルでは、NetBeans Ruby on Rails プロジェクトのモデル間の関係 (1 対 1 および 1 対多) を構築する方法を説明します。
目次
このチュートリアルを使用するには、次のソフトウェアが必要です。
* このチュートリアルは Rails 1.2.5 向けに記述されており、スキャフォールドに言及しています。スキャフォールドは Rails 2.0 ではサポートされていないので、このチュートリアルで Rails 2.0 を使用することはできません。
サンプルデータベースの作成
このチュートリアルは、「Ruby のブログを 10 分で作成」というチュートリアルに基づいて作成されています。このチュートリアルをすでに終了している場合、チュートリアルで構築したプロジェクトを使用して開始し、次の節に進むことができます。終了していない場合、RubyWebLog.zip ファイルをダウンロードし、サンプルデータベースを作成する手順に従ってください。
注: このチュートリアルでは、MySQL データベースサーバーを使用します。Ruby アプリケーションでの MySQL データベースサーバーの使用については、「Ruby サポートのインストールと設定」を参照してください。この記事では、代わりに Java DB データベースサーバーを使用する方法も説明します。
- コマンドウィンドウを開きます。
- MySQL データベースサーバーをまだ起動していない場合、起動します。
- 次のコマンドを入力して開発用データベースを作成し、Enter キーを押します。
mysqladmin -u root -p create rubyweblog_development
注: root ユーザーにパスワードが必要ない場合、引数 -p を省略してください。
IDE で rubyweblog プロジェクトを開きます。
注: IDE で Ruby プロジェクトを最初に開くか、または作成すると、バンドルされた JRuby ソフトウェア以外に Ruby のインストールが存在するかどうかが IDE によって確認されます。存在する場合、使用するソフトウェアを選択するよう求めるダイアログが表示されます。バンドルされた JRuby インタプリタを使用する場合は、「JRuby」を選択します。これ以外のインストールされている Ruby を使用する場合は、その Ruby を選択します。詳細は、「Ruby サポートのインストールと設定」チュートリアルの「独自の Ruby インストールを使用するための IDE の設定」を参照してください。
データベースにパスワードが必要な場合は、database.yml ファイルを編集し、開発構成の下にパスワードを指定します。ファイルを保存します。
database.yml ファイルにすばやくアクセスするには、Alt-Shift-O キー (Mac の場合は Ctrl-Shift-O キー) を押して、「ファイル名」テキストフィールドに「database.yml」と入力し、Enter キーを押します。
-
「rubyweblog」ノードを右クリックし、「データベースマイグレーション」>「現在のバージョンへ」を選択します。
このアクションによってデータベースが更新され、posts 表が取り込まれ、body フィールドに追加されます。マイグレーションが完了すると、「出力」ウィンドウに示されます。
-
アプリケーションを実行して新しい投稿を作成します。
Comment モデルの作成
このチュートリアルでは rubyweblog を改良し、読者がブログ投稿にコメントを書き込めるようにします。最初に、Comment モデルを作成し、読者のコメントのインスタンスを格納します。プロジェクトにはすでに、ブログ投稿のインスタンスを格納するための Post モデルがあります。
-
「プロジェクト」ウィンドウの rubyweblog ノードが展開されていない場合は展開し、「モデル」ノードを右クリックして「生成」を選択します。
「引数」フィールドで「Comment post_id:integer created_at:datetime comment:text」と入力し、「了解」をクリックします。
Rails ジェネレータが Comment という名前のモデルを作成します。このモデルには、次のファイルが含まれています。
- app/models/comment.rb。Comment モデルのメソッドを保持するファイル。
このファイルは編集領域で開きます。
- test/unit/comment_test.rb。モデル確認用の単体テスト。
-
test/fixtures/comments.yml。モデル生成用のテストフィクスチャー。
-
db/migrate/migrate/003_create_comments.rb。データベース構造を変更するためのマイグレーションファイル。プロジェクトにはすでに posts 表の作成と変更用に
001_create_posts.rb と 002_add_body.rb という 2 つのマイグレーションファイルがあるため、このファイルのバージョンは 003 です。
データベースのマイグレーション
次に作業するのは 003_create_comments.rb というマイグレーションファイルです。
「出力」ウィンドウで 003_create_comments.rb ファイルへのリンクをクリックします。
ファイルが開き、次のコード例に示すように、comments という表を作成する self.up メソッド、および comments 表を破棄する self.down メソッドが作成されます。
class CreateComments < ActiveRecord::Migration
def self.up
create_table :comments do |t|
t.column :post_id, :integer
t.column :created_at, :datetime
t.column :comment, :text
end
end
def self.down
drop_table :comments
end
end
このマイグレーションにより、4 つのフィールドがある comments 表が作成されます。フィールド「id」には整数、「post_id」には整数、「created_at」には日付と時刻、および「comment」にはテキストの記述が含まれます。
「rubyweblog」ノードを右クリックし、「データベースマイグレーション」>「現在のバージョンへ」を選択します。
このアクションによってデータベースが更新され、comments 表が取り込まれます。マイグレーションが完了すると、「出力」ウィンドウに示されます。
Comment モデルと Post モデル間の関係の定義
現在、アプリケーションには 2 種類のモデルがあります。新しいブログ投稿を作成する Post モデルと、ブログ投稿にコメントを付け加える Comment モデルです。ここでは、この 2 つのモデル間の関係を定義し、1 つの投稿に 1 つのコメントを関連付けたり、1 つの投稿に複数のコメントを格納したりできるようにします。
- 「モデル」ノードを展開し、
post.rb を開きます。
-
次のように has_many 結合を post.rb に追加します。
class Post < ActiveRecord::Base
validates_presence_of :title, :body
has_many :comments
end
has_many メソッドは、関連付けられた 0、1、または複数のコメントレコードを、投稿が持つことができることを示します。
トリガー「hm」を入力して Tab キーを押すと、コードテンプレート has_many :objects に展開します。
-
次のように、「モデル」>「comment.rb」を開き、belongs_to 結合を追加します。
class Comment < ActiveRecord::Base
belongs_to :post
end
belongs_to メソッドは、1 つのコメントは 1 つの投稿だけに関連付けできることを示しています。
デフォルトでは、ActiveRecord は post_id を使用して、対応する post.id. を持つ投稿に、コメントを関連付けます。
トリガー bt は belongs_to :object に展開します。
コントローラのスキャフォールドの変更
次に、スキャフォールドを生成するコントローラ blog_controller.rb で作業します。スキャフォールドとは、ブログ投稿のエントリを作成、読み込み、更新、および削除するための基本インタフェースです。
-
「コントローラ」ノードを展開し、blog_controller.rb を開きます。
コントローラには、index、list、show、new、create、edit、update、destroy などの、すべてのスキャフォールドのアクションがあります。
-
次のコード例に示すように show アクションを変更し、post_id をフラッシュに保存します。
def show
@post = Post.find(params[:id])
flash[:post_id] = @post.id
end
コードは、要求時に渡された id パラメータに関連付けられている投稿を検索します。次に、あとで利用できるよう id をフラッシュに保存します。フラッシュは HTTP セッションに似ていますが、1 回の要求内でのみ有効です。フラッシュに何かを格納すると、次の要求時に利用したあとで消えます。そのためにフラッシュと呼ばれます。
-
blog_controller.rb ファイルの末尾に移動し、次の post_comment アクションを最後の end 文の前に追加します。
def post_comment
@comment = Comment.new(
"post_id" => flash[:post_id],
"created_at" => Time.now,
"comment" => params[:comment]['comment']
)
if @comment.save
flash[:notice] = 'Comment was successfully added.'
redirect_to :action => 'show', :id => flash[:post_id]
end
end
ユーザーが「Post」ボタンをクリックしてコメントを送信すると、post_comment アクションが呼び出されます。コードの最初のブロックは、フラッシュから post_id (1、2 など) を取得し、その id を使用して、関連付けられているブログ投稿を探します。次に、コードではその post_id に関連付ける新規の Comment オブジェクトを作成します。また、これには作成時刻と実際のコメントも含まれます。Rails のフレームワークでは、ページから送信されたパラメータをハッシュとして渡し (params[:comment])、ここからコードがコメントのパラメータを抜き出します (params[:comment]['comment'])。
Comment は ActiveRecord クラスであるため、この save メソッドを呼び出すと、コメントレコードがデータベースに保存されます。
メッセージはフラッシュに格納されます。コードは show アクションを呼び出し、show.rhtml ページを読み込みます。このページでは、新規分も含め、投稿とそのコメントすべてが再読み込みされます。
コメントを追加できるようビューを変更
ここでは、個々のブログエントリを表示する show.rhtml ファイルを編集します。
-
「ビュー」>「blog」を展開し、
show.rhtml を開きます。
-
show.rhtml の末尾に次のコードを追加します。
<hr>
<h4>Comments</h4>
<% form_tag :action => 'post_comment' do %>
<p><label for="comment_comment">Comment</label><br/>
<%= text_area 'comment', 'comment' %></p>
<%= submit_tag "Post" %>
<%end %>
このコードでは、次の図に示すように、コメント記入用のテキスト入力領域と、「Post」とラベル付けされた送信ボタンを含むフォームを作成します。フォームを送信すると、post_comment アクションが呼び出されます。
-
ファイルを保存し、アプリケーションを実行します。
-
Permalink をクリックしてブログエントリの詳細を表示します。テキスト領域にコメントを追加してみてください。ただし、「Post」ボタンをクリックしても、まだブログにコメントは表示されません。
投稿が正常に完了すると、次の図に示すように、ビューの最上部にメッセージが表示されます。次の段階では、コメントを収集して表示するコードを追加します。
コメントの表示
このブログでは読者が書き込んだコメントがまだ表示されないので、ここでその問題を修正します。
-
blog_controller.rb で show アクションを検索し、次のように post_comments インスタンス変数を挿入してコメントを収集します。
def show
@post = Post.find(params[:id])
@post_comments = @post.comments.collect
flash[:post_id] = @post.id
end
has_many :comments 関係を Post モデルに追加したので、@post.comments を呼び出すことによって、投稿のすべてのコメントにアクセスできます。
-
<h4>Comments</h4> 行のすぐ後ろに、次の <ul> タグの内容をコピー&ペーストして、show.rhtml を変更します。
<ul>
<% @post_comments.each do |comment| %>
<li><%= h comment.comment %><br>
<div style="color: #999; font-size: 8pt">
Posted on <%= comment.created_at.strftime("%B %d, %Y at %I:%M %p") %>
</div>
</li>
<% end %>
</ul>
このコードはコメントにスタイルを適用し、中黒の一覧で表示し、コメントが投稿された日付と時刻を追加します。
-
「ファイル」>「すべてを保存」を選択してから、ブラウザを再表示します。
次の図に示すように、コメントが中黒の一覧でブログに表示されます。
次の手順
>> その他の NetBeans Ruby ドキュメント