2011年9月11日日曜日

Rails3を初歩から学ぶ#18 エラーメッセージの表示

この一連のエントリは
Ruby on Rails 3 Tutorial: Learn Rails by Example (Addison-Wesley Professional Ruby Series)
で参考に学んだことを凝縮してお送りしています。

前回先にリンクだけつくってしまったのでユーザー情報の編集ページをつくりましょう。
最終的には映画情報(忘れているかもしれませんが、これはお気に入りの映画を登録するアプリケーションなのでした!)を編集できるようにしますが、とりあえず現時点ではユーザー名とパスワードのみ変更可能とします。
まずはeditアクション用のテストケースです。

describe "GET 'edit'" do
describe "未認証ユーザーの検証" do
it "未認証ならサインインページに遷移すること" do
user = Factory(:user)
get :edit, :id => user
response.should redirect_to(new_session_path)
end
end #未認証ユーザーの検証
describe "認証済みユーザーの検証" do
before(:each) do
@user = Factory(:user)
controller.sign_in(@user)
end
it "アクセスできること" do
get :edit, :id => @user
response.should be_success
end
it "タイトルの検証" do
get :edit, :id => @user
response.should have_selector("title", :content => "設定変更")
end
it "パスワード確認フィールドが存在すること" do
get :edit, :id => @user
response.should have_selector("input[name='user[password_confirmation]'][type='password']")
end #代表してここだけ調べる

end #認証済みユーザーの検証
end #GET edit
フィールド一個しか見てないとか若干の手抜き感がありますが、特に目新しいことは無いのでこのまま進めます。
次にコントローラの実装です。
before_filter :authenticate, :except => [:new, :create]
def edit
@title = "設定変更"
@user = User.find(params[:id])
end

フィルタなんですがこれまでは「:only」で対象となるアクションを指定していましたが、認証が不要なページの方が少ないので「:except」で認証が不要なページのみを指定するようにしています。
次はapp/views/users/edit.html.erbを以下のように編集します。

<h1>設定変更</h1>
<%= form_for(@user) do |f| %>
<%= render 'fields', :f => f %>
<div class="actions">
<%= f.submit "更新" %>
</div>
<% end %>
新規登録時と同じフォームを表示するので部分テンプレート化しました。
new.html.erbも部分テンプレートを呼び出すように変更します。
<h1>ユーザー新規登録</h1>
<%= form_for(@user) do |f| %>
<%= render 'fields', :f => f %>
<div class="actions">
<%= f.submit "新規登録" %>
</div>
<% end %>
さっぱりしました。では部分テンプレートをつくりましょう。
app/views/users/_fields.html.erbです。

<%= render 'shared/error_messages', :object => f.object %>
<div class="field">
<%= f.label :name %><br />
<%= f.text_field :name %>
</div>
<div class="field">
<%= f.label :password %><br />
<%= f.password_field :password %>
</div>
<div class="field">
<%= f.label :password_confirmation, "Confirmation" %><br />
<%= f.password_field :password_confirmation %>
</div>
2行目以降は元々new.html.erbにあった内容そのものです。
これまでは入力内容がUserモデルで定義した妥当性検証でNGになった場合に何も表示していませんでしたが、なぜエラーになったのかメッセージを表示するようにしました。
エラーの格納方法はRailsで共通なので使い回しできるようapp/views/shared/以下に部分テンプレートを用意します。名前は「_error_messages.html.erb」です。

<% if object.errors.any? %>
<div id="error_explanation">
<h2>登録できませんでした</h2>
<p>以下の内容をご確認ください</p>
<ul>
<% object.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>


ここのobjectというのは呼び出し元をたどっていくと@userになります。
Userモデルの検証結果(validatesの実行結果)を@userインスタンス変数がもっていますので、この内容を表示しています。
エラーメッセージは英語です。
日本語化する方法もありますが、ここでは実施しません。
こちらのページに手順が紹介されています。

rails3 エラーメッセージ日本語化のメモ

0 件のコメント:

コメントを投稿