はじめに
Railsを学習し始めた頃は部分テンプレートに苦手意識がありましたが、ネットで見つけた、部分テンプレートを用いたエラー表示の書き方を見て理解が深まったので共有します。
背景
例えば、ユーザーや本に関する投稿ができるアプリがあるとして、最初のうちはユーザーと本それぞれの新規投稿画面new.html.erb
の上部に以下のようなエラー文を書いていました。
<% if @book.errors.any? %>
<%= @book.errors.count %>件のエラーが発生しました
<% @book.errors.full_messages.each do |message| %>
<%= message %>
<% end %>
<% end %>
<% if @user.errors.any? %>
<%= @user.errors.count %>件のエラーが発生しました
<% @user.errors.full_messages.each do |message| %>
<%= message %>
<% end %>
<% end %>
しかし、これだとDRYの原則にも反しますし、編集画面edit.html.erb
にも書くとなると面倒です。
解決策
エラー表示を以下のように部分テンプレート化する方法を知りました。まず、errors
フォルダ下に_errors.html.erb
ファイルを用意します。
<% if obj.errors.any? %>
<%= obj.errors.count %>件のエラーが発生しました
<% obj.errors.full_messages.each do |message| %>
<%= message %>
<% end %>
<% end %>
この書き方の優れている点は、objという(中性的なイメージの?)ローカル変数を用いることで、objに@book
や@user
などさまざまなインスタンス変数を渡すことができる点です。
例えば、本の新規投稿画面なら、@book = Book.new
というインスタンス変数をobjに渡すことで、
<%= render "errors/errors", obj:@book %>
と書けますし、ユーザーの編集画面なら、@user = User.find(params[:id])
というインスタンス変数をobjに渡すことで、
<%= render "errors/errors", obj:@user %>
と書くことができます。このようにできるのも、エラー表示が様々なモデルに共通して同じ形式であるおかげです。
結論
今では当たり前となりましたが、当初は、部分テンプレートのローカル変数に@book
や@user
などの異なるモデルからなる様々なインスタンス変数を渡してエラー表示するやり方に目が覚める思いで、部分テンプレートの真髄を見たような気がしました。エラー表示以外にも多くの画面で共通のもの(ヘッダー、フッターはもちろん他にも何かありそう)は積極的に部分テンプレートを使っていきたいです。