リファクタリングと入力チェック機能の追加

このセクションでは 「コメント登録機能の追加 - (2)コメントの追加・削除」で作成したアプリケーションに対して、部分テンプレートを用いてリファクタリングする手順と、入力チェック機能を追加する手順について解説します。

 

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

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

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

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

 

部分テンプレートによるリファクタリング

複数のビューで同じ表示(HTMLレイアウト)がある場合、それを「部分テンプレート」として切り出し共通化することができます。部分テンプレートを各ビューに埋め込んで使用することで、重複がなくなりプログラムのメンテナンス性を向上することができます。ここではコメントデータを扱う処理を部分テンプレートとして切り出して定義し、ビューに埋め込む手順について説明します。

 

ビューの修正

コメント登録機能の追加 - (1)コメントの表示」で作成した画面のビュー "RAILS_ROOT\app\views\home\page.html.erb"に対して、コメントの一覧表示の箇所と、コメントを追加する箇所を部分テンプレート化します。部分テンプレートの埋め込みには、renderメソッドを用います。

 <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>

+ <%= render 'comments/list' %>
- <h3>コメント:</h3>
- <% @article.comments.each do |comment| %>
- <h4><%= comment.from %> さん</h4>
- <pre><%= comment.body %></pre>
- <p>[<%= link_to 'コメントを削除する', [@article, comment],
- confirm: 'Are you sure?', method: :delete %>]</p>
- <% end %>

<hr />
+ <%= render 'comments/form' %>
- <h3>コメント追加:</h3>
- <%= form_for [@article, @comment] do |f| %>
- <p>from:</p><p><%= f.text_field :from %></p>
- <p>comment:</p><p><%= f.text_area :body, :rows => 5 %></p>
- <%= f.submit 'コメントを投稿する' %>
- <% end %>

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

※行頭に「-」を付けた行は「部分テンプレート」化するため削除したコード

※行頭に「+」を付けた行は「部分テンプレート」化したコードを読み込むために追加したコード

 

コメント一覧表示の部分テンプレート作成

"RAILS_ROOT\app\views\comments\_list.html.erb"を新規作成し、先ほどのビューのコメント一覧表示の箇所を部分テンプレートにします。部分テンプレートでは、ファイル名の先頭はアンダースコア「_」となります。

<h3>コメント:</h3>
<% @article.comments.each do |comment| %>
<h4><%= comment.from %> さん</h4>
<pre><%= comment.body %></pre>
<p>[<%= link_to 'コメントを削除する', [@article, comment],
confirm: 'Are you sure?', method: :delete %>]</p>
<% end %>

 

コメント入力欄の部分テンプレート作成

"RAILS_ROOT\app\views\comments\_form.html.erb"を新規作成し、先ほどのビューのコメント入力欄の箇所を部分テンプレートにします。

<h3>コメント追加:</h3>
<%= form_for [@article, @comment] do |f| %>
<p>from:</p><p><%= f.text_field :from %></p>
<p>comment:</p><p><%= f.text_area :body, :rows => 5 %></p>
<%= f.submit 'コメントを投稿する' %>
<% end %>

 

 

入力チェック機能の追加

Railsではアプリケーションの入力データを検証する機能としてvalidationという仕組みがあります。validationを用いると、入力データのフォーマットや属性、ユニークな値かどうかなどをチェックする機能を簡単に実装することができます。以下では、コメントの投稿者またはコメント内容(コメントテーブルのfromカラムとbodyカラム)が未入力のまま投稿しようとすると、警告画面を出すようにします。

 

validationの実装

コメントを扱うモデルクラスComment("RAILS_ROOT\app\models\comment.rb")に項目fromおよびbodyの両方が入力されているかどうかチェックするためのvalidationを実装します。Railsのvalidationには様々な種類がありますが、今回はvalidate_presence_ofメソッドを用いて機能を実装します。

 class Comment < ActiveRecord::Base
+ validates_presence_of :from, :body
belongs_to :article
end

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

 

コントローラーのコメント追加処理の修正

コメントのコントローラー"app\controller\comments_controller.rb"のCommentsControllerのcreateメソッドに、入力値に不備があった場合の処理を追加します。

 class CommentsController < ApplicationController
def create
@article = Article.find(params[:article_id])
@comment = @article.comments.create(params[:comment])
- redirect_to page_path(params[:article_id])
+ if @comment.errors.empty?
+   redirect_to page_path(params[:article_id])
+ else
+ @article.comments.delete @comment
+ render template: 'home/page'
+ end
end

 以下略
  :

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

 

エラーメッセージ表示欄の追加 

コメント入力欄の部分テンプレート"RAILS_ROOT\app\views\comments\_form.html.erb"に、エラーメッセージを表示する欄を以下のように追加します。

 <h3>コメント追加:</h3>
+<% if @comment.errors.any? %>
+ <div id="error_explanation">
+ <p>
+ <h2>コメントの入力に<%= @comment.errors.count %>件の誤りがあります。
+ </h2>
+ </p>
+ <ul>
+ <% @comment.errors.full_messages.each do |msg| %>
+ <li><%= msg %></li>
+ <% end %>
+ </ul>
+ </div>
+<% end %>
<%= form_for [@article, @comment] do |f| %>
<p>from:</p><p><%= f.text_field :from %></p>
<p>comment:</p><p><%= f.text_area :body, :rows => 5 %></p>
<%= f.submit 'コメントを投稿する' %>
<% end %>

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

 

入力チェック機能の確認

"from"または"comment"のどちらかを未入力にしてコメントを投稿すると、以下のようにエラーメッセージが表示されます。

入力チェック機能の確認