コメント登録機能の追加 - (1)コメントの表示

このセクションでは「トップページ機能の追加」を拡張し、ブログ記事で"コメント"を扱う以下の機能を追加する手順を開設します。

 (1)コメントの表示  ・・・   記事のコメント数、コメント一覧を表示する機能(このページで解説)
 (2)コメントの追加・削除  ・・・   記事にコメントを追加・削除する機能(次のページで解説)

 

<チュートリアルを進めるにあたって>

  •  ・アプリケーション名は"blog"、アプリケーションのルートフォルダは、"c:¥rails_apps¥blog"とします

  •  ・アプリケーションのルートフォルダのパスは、"RAILS_ROOT"と記載します

 ・コマンドプロンプトを用いた操作は、特別な指定がない限り全て"RAILS_ROOT"に移動した状態で行います

 

コメントを扱うテーブルの設計

ブログ記事へのコメントを扱うテーブルを以下のとおり設計します。

 "コメントテーブル"の名前 : comments
 カラム名  格納する内容  役割 
 id  コメントのID  PRIMARY KEY 
 article_id 
 コメントした記事のID 
 FOREIGN KEY(※) 
 from  記入者の名前  -
 body   コメントの内容  -

※"article_id"カラムは、記事テーブル(articles)のレコードを参照するための外部キー

 

参考:FOREING KEY(外部キー)

Railsではカラム名が"参照テーブル名の単数形_id" のとき、それをFOREIGN KEY(外部キー)として扱うよう設計されています。

 

マイグレーションファイル、モデルクラスの作成

Generatorを用いて、コメントを扱うためのテーブル(comments)を生成するためのマイグレーションファイルと、コメントデータを扱うためのモデルクラス(Comment)を作成します。

コマンドプロンプトで「rails generate model Comment article:references from:string body:text」とタイプしてEnterキーを押下します。FOREIGN KEYは「参照テーブル名の単数:references」で指定しています。コマンドプロンプト上には、ファイル・フォルダが自動生成される様子が以下のように表示されます。 

c:\rails_apps\blog>rails generate model Comment article:references
from:string body:text
invoke active_record
create db/migrate/20111224022145_create_comments.rb
create app/models/comment.rb
invoke test_unit
create test/unit/comment_test.rb
create test/fixtures/comments.yml

 

 

コメントテーブルの作成

マイグレーションを実行してコメントテーブル"comments"をデータベースに作成します。

コマンドプロンプトで「rake db:migrate」とタイプしてEnterキーを押下します。コマンドプロンプト上には、テーブルが生成される様子が以下のように表示されます。

c:\rails_apps\blog>rake db:migrate
== CreateComments: migrating =================================================
-- create_table(:comments)
-> 0.1702s
-- add_index(:comments, :article_id)
-> 0.0000s
== CreateComments: migrated (0.1702s) ========================================

 

 

アソシエーションの定義

"アソシエーション"とは、テーブル間のリレーションシップをモデル上の関係として操作できるようにする仕組みのことです。アソシエーションが定義されたモデルクラスを用いると、モデルクラスのインスタンスから、関連付けられたモデルクラスを通じてデータを容易に操作することができます。

今回のブログアプリケーションの場合、1件の記事(記事テーブルのレコード1件)に対し、コメントが0~N件(関連するコメントテーブルのレコードが0~N件)登録されることになります。つまり"1対多"の関係になっています。このような記事テーブル(articles)とコメントテーブル(comments)の関係を表すアソシエーションを定義するには、"RAILS_ROOT\app\models\article.rb"のArticleモデルのクラス定義で以下のように実装します。

 class Article < ActiveRecord:base
+ has_many :comments
end

※行頭に"+" が付いた行が追加したコードです。

 

一方、"RAILS_ROOT\app\models\comment.rb"のCommentモデルのクラスには「belongs_to :article」が生成時に記述されており、コメントテーブルの各レコードは記事テーブルのレコードと"多対1"の関連があることを指定しています。

class Comment < ActiveRecord::Base
belongs_to :article
end

 

上記のように実装することで、プログラム上では以下のような実装が可能になります。

# id=1の記事(Articleモデルのインスタンス)を取得する
article = Article.find(1)

# 記事にコメントを2件登録する
article.comments.create(:from => 'rubyist', :body => 'comment1')
article.comments.create(:from => 'rubyist', :body => 'comment2')

# 記事のコメント数を取得する
article.comments.count

# id=1の記事に関連するコメント(の配列)を1件づつ操作する
article.comments.each do |comment|
  # commentは、Commentモデルのインスタンス
end

 

 

アソシエーションの確認

定義したアソシエーションの機能を、Railsのコンソール機能を用いて確認します。

 

コンソールの起動

コマンドプロンプトで、「rails console」とタイプしてEnterキーを押下します。コンソールが起動すると、以下のようにプロンプトが変わります。

c:\rails_apps\blog>rails console
Loading development environment (Rails 3.1.3)
irb(main):001:0>

 

アソシエーションの確認

コンソールで以下のようにタイプして、アソシエーションの機能を確認します。以下ではタイプするコードのみを表示します。実際には各行を実行する度にプログラムの実行結果が表示されます。

irb(main):001:0> article = Article.first    #最初のレコードを取得
irb(main):002:0> article.comments.create(:from => 'rubyist',
irb(main):003:1* :body => 'comment1') #コメントを登録
irb(main):004:0> article.comments.create(:from => 'rubyist',
irb(main):005:1* :body => 'comment2')
irb(main):006:0> article.comments.count #コメント数を取得
=> 2 # 2件のコメントが登録されていることが確認できる。

 

コンソールの終了

「exit」とタイプしEnterキーを押下すると、コンソールが終了します。

 

コメント数表示の追加

 

コメント数表示を行うビューの実装

トップページのビュー"RAILS_ROOT\app\views\home\index.html.erb"に、記事に関連するコメントの登録件数を表示させるコードを以下のように追加します。

※文字コードはUTF-8で保存してください。   

 <% @articles.each do |article| %>
<div style="width:500px;border:1px solid #ccc;margin:5px">
<div style="float:left">
<h2 ><%= article.title %></h2>
</div>
<div style="clear:both">
<pre><%= article.content %></pre>
+ コメント(<%= article.comments.count %>)
</div>
</div>
<% end %>

※行頭に"+"がついた行が追加したコードです。

 

コメント数表示の確認

アプリケーションを起動して、ブログのトップページ 「http://localhost:3000/」にアクセスすると、コンソールで登録したコメントの件数が以下のように表示されることが確認できます。

 ブログトップページ(コメント数表示)

 (ブログトップページ :コメント数表示)

 

コメント一覧表示の追加

続いて“記事に付けられたコメントを一覧表示する画面”をブログアプリに追加します。この画面には「http://localhost:3000/page/記事のid」のURLでアクセスすることとします。

 

記事データ取得処理の実装

pageアクションをコントローラに実装します。RAILS_ROOT\app\controllers\home_controller.rbにあるHomeControllerクラスでpageメソッドを定義し、その中で対応する記事データを取得する処理を実装します。Article.findメソッドではページidを引数params[:id]にセットし、返り値である記事を@articleに格納します。

 class HomeController < ApplicationController
def index
@articles = Article.all
end

+ def page
+ @article = Article.find(params[:id])
+ end
end

※行頭に"+"がついた行が追加したコードです。 

 

記事のコメントを一覧表示する画面の実装

上記で追加したHomeController#pageで使用するビューとして"RAILS_ROOT\app\views\home\page.html.erb"を新規作成します。このビューでは、記事のタイトルと内容、記事へのコメント一覧を表示するようにするため、以下のように実装します。ページの最後には、トップページに戻るリンクをlink_toで記述します。

<div style="width:500px;border:1px solid #ccc;margin:5px">
<div style="float:left">
<h2 ><%= @article.title %></h2>
</div>
<div style="clear:both">
<pre><%= @article.content %></pre>
</div>

<h3>コメント:</h3>
<% @article.comments.each do |comment| %>
<h4><%= comment.from %> さん</h4>
<pre><%= comment.body %></pre>
<% end %>

<div style="float:right">
<%= link_to 'トップページに戻る', root_path %>
</div>
</div>

 

ルーティング設定

"RAILS_ROOT\config\routes.rb"に、URL"http://localhost:3000/page/記事のid"が呼ばれた時のルーティング定義を記述します。

 Blog::Application.routes.draw do
resources :articles

get "home/index"
+ match "page/:id" => 'home#page', :as => 'page'

  以下略
   :

※行頭に"+"がついた行が追加したコードです。

 

トップページからのリンク設定

トップページのビュー"app\views\home\index.html.erb"で、記事のタイトルをクリックしてコメント一覧へのページに遷移するようにするため、以下のように実装します。

 <% @articles.each do |article| %>
<div style="width:500px;border:1px solid #ccc;margin:5px">
<div style="float:left">
- <h2 ><%= article.title %></h2>
+ <h2 ><%= link_to article.title, page_path(article) %></h2>
</div>
<div style="clear:both">
<pre><%= article.content %></pre>
コメント(<%= article.comments.count %>)
</div>
</div>
<% end %>

※行頭に"-" が付いた行が削除したコードです。
※行頭に"+" が付いた行が追加したコードです。

 

記事ごとにコメントを一覧表示する画面の確認

トップページで記事のタイトルをクリックすると、記事のタイトルと内容、登録されたコメントが、以下の画面のように表示されます。

 記事ごとにコメントを一覧表示する画面

 (記事ごとにコメントを一覧表示する画面)

 

コメント登録機能の追加 - (2)コメントの追加・削除」に続きます。