更新日:
【Rails】 部分テンプレートの使い方を徹底解説!
部分テンプレートとは、複数のビューファイルの中で使われている部分を一つのビューファイルとして管理する時に使います。
application.html.erb
にはヘッダーやフッターなど全てのビューファイルで共通する部分を記述しました。
この他にもアプリを作成しているとサイドバーなど複数のページで共通して表示させたい部分が結構あります。
そんな時に、複数のビューファイルの共通部分として作成するのが部分テンプレートです。
部分テンプレートの使い方
この章では、部分テンプレートの使い方について解説します。
部分テンプレートを作成しよう
部分テンプレートとしてビューファイルを作成する時は_sidemenu.html.erb
のようにファイル名の前に_
(アンダースコア)をつける必要があります。
このようなファイル名で作成すると部分テンプレートとして使うことができます。
部分テンプレートを呼び出してみよう
それでは今作成した部分テンプレートを呼び出してみましょう。
コントローラーやビューファイルの中でビューファイルを呼び出すにはrenderメソッドを使用します。
renderメソッド
指定したテンプレートを呼び出す時に使うメソッドです。
下記のように記述します。
1
2
render 'ファイル名' # 指定したテンプレートファイルを呼び出す
render :アクション名 # 指定したアクションのテンプレートファイルを呼び出す
renderメソッドは色々な形でビューを呼び出すことができます。
そのため「部分テンプレートを呼び出しているよ」ということを明示的にする時はオプションを使って下記のように記述することもできます。
1
render partial: 'ファイル名'
renderメソッドを記述したビューファイルと違うフォルダ内の部分テンプレートを呼び出すときは hoges/hoge
のようにどのフォルダの部分テンプレートを使用しているかを記述する必要があります。
1
render partial: 'hoges/hoge'
下の例だと_right_content.html.erb
はこのコードを記述しているindex.html.erb
と同じフォルダにあるのでそのままファイル名を記述すれば呼び出すことができます。
_menu_html.erb
はlayoutsフォルダ内にあるので、呼び出す際はlayouts/menu
と記述する必要があります。
partialオプション
partialオプションは部分テンプレートを呼び出す時に使います。
「呼び出しているのは部分テンプレートだよ」と強調したいだけなので、つけなくても構いません。
ですがlocalsオプション
を使用した時はつけないとエラーが出ます。
localsオプション
localsオプション
を使うと部分テンプレート内で使う変数の定義をすることができます。
例えば部分テンプレート内で変数を使いたい場合、どこかで変数を定義する必要がありますね。
そんな時にはlocalsオプション
を使って変数を定義します。
1
2
3
4
5
6
<%= render partial: 'ファイル名', locals: { '部分テンプレート内で使う変数': '変数に入れる値' } %>
<!--例 テンプレート内の「hoge」という変数に「こんにちは」が代入される -->
<%= render partial: 'hoge', locals: { hoge: 'こんにちは' } %>
<!-- 例 テンプレート内の「hoge」という変数に呼び出し元で定義した変数「hoge」が代入される-->
<%= render partial: 'hoge', locals: { hoge: hoge } %>
前述したとおりlocalsオプション
を使った場合はpartial
は省略できません。
partial
を省略して書きたければ下記のように必ずlocalsオプション
も省略しないといけないので注意しましょう。
1
2
3
4
<%= render 'hoge', hoge: hoge %>
<!-- localsオプションを記述しているとエラー -->
<%= render 'hoge', locals: { hoge: hoge } => エラーが発生 %>
変数を複数定義してみよう
localsオプション
では部分テンプレート内で使用する変数を複数定義することができます。
例をみてみましょう。
1
<%= render partial: 'hoge', locals: { name: "山田", adrress: "東京都渋谷区", age: 20 } %>
上の例だと部分テンプレート内で使用するname
、adrress
、age
という3つの変数を定義しています。
実際に部分テンプレート内で使用してみます。
1
2
3
<p>私の名前は<%= name %>です。</p>
<p>私は<%= address %>に住んでます。</p>
<p>私は<%= age %>です。</p>
このように記述すると下のように表示されます。
このように部分テンプレートで使用する変数は複数定義することもできます。
記述例を見てみよう
それでは実際部分テンプレートをどのように使うのか確認してみましょう。
今回はnewアクションとeditアクションで使うビューを例にしてみます。
1
2
3
4
5
6
7
def new
@article = Article.new
end
def edit
@article = Article.find(params[:id])
end
1
2
3
4
5
6
7
8
9
<%= form_for @article do |f| %>
<%= f.label :name %>
<%= f.text_field :name %>
<%= f.label :title %>
<%= f.text_field :title %>
<%= f.label :body %>
<%= f.text_area :body %>
<%= f.submit %>
<% end %>
1
2
3
4
5
6
7
8
9
<%= form_for @article do |f| %>
<%= f.label :name %>
<%= f.text_field :name %>
<%= f.label :title %>
<%= f.text_field :title %>
<%= f.label :body %>
<%= f.text_area :body %>
<%= f.submit %>
<% end %>
投稿フォームと編集フォームはform_forというヘルパーメソッドを使っているため、全く同じコードで書くことができます。
ですのでここは部分テンプレートとして置き換えられそうですね。
共通する部分を_form.html.erb
という名前のファイルを作成し記述します。
今回はローカル変数として変数を定義するので@article
からarticle
に変えておきます。
※インスタンス変数だと使われる範囲が部分テンプレートの中だけに限定することができないため
1
2
3
4
5
6
7
8
9
<%= form_for article do |f| %>
<%= f.label :name %>
<%= f.text_field :name %>
<%= f.label :title %>
<%= f.text_field :title %>
<%= f.label :body %>
<%= f.text_area :body %>
<%= f.submit %>
<% end %>
そしてnew.html.erb
とedit.html.erb
を下記のように編集します。
1
<%= render partial: 'form', locals: { article: @article } %>
partial:
の部分は部分テンプレート名を記述するのでした。
部分テンプレート名は_form
とアンダーバーが付いていますが、呼び出す際は_
は付けません。
また今回は部分テンプレート内でarticle
という変数を使っているのでlocals: { article: @article }
と指定します。
左のarticle
の部分は部分テンプレート内で使うときの変数名を記述します。
今回作成した部分テンプレート_form.html.erb
の中ではarticle
という変数を使っているのでarticle
と指定しています。
右の@article
の部分はコントローラーやビューで定義した変数名を記述します。
今回はコントローラーのnewアクションとeditアクションで定義した@article
を指定しています。
上のコードが下の1行のコードになりました。
もちろんnew.html.erb
だけでなくedit.html.erb
も1行で書くことができます。
このように共通している全てのファイルで部分テンプレートを呼び出す記述に置き換えることができます。
手元に置いておきたい1冊
こちらの「プロを目指す人のためのRuby入門」は、Rubyの特徴から例外処理、デバック技法など実務で必要となる知識を一通り学ぶことができます。
豊富なサンプルコードと丁寧な解説でしっかり理解できるように書かれている良書です。
Ruby on Railsは、Rubyで書かれたフレームワークです。Railsで使用される構文はRubyの構文が大半です。そのためRubyをしっかり学習することでRailsへの理解が深まります。
Rubyは触りだけでRailsの扱い方に学習時間を費やす、もしくはRailsから学習している方もいますが、いずれにしても並行してRubyを学ぶと良いでしょう。
手を動かしながらRubyを学べる丁寧な技術書です!
言語仕様からテスト駆動開発・デバッグ技法まで
他のオプションを確認してみよう
renderメソッドには他にもオプションが用意されています。
例えば下記のようなコードがあったとします。
1
2
3
4
5
<% @hoges.each do |hoge| %>
<%= hoge.name %>
<%= hoge.title %>
<%= hoge.body %>
<% end %>
このコードが何箇所でも使われているので下記のような部分テンプレートを作成したとします。
_hoge.html.erb
この部分テンプレートを使用するので下記のようにビューファイルを編集します。
1
2
3
<% @hoges.each do |hoge| %>
<%= render partial: 'hoge', hoge: hoge %>
<% end %>
上のコードは@hoges
の要素の分だけ部分テンプレートが繰り返し呼び出されて表示されます。
この3行のコードをcollectionオプションを使うと下記のように1行で記述することができます。
1
<%= render partial: 'hoge', collection: @hoges %>
collectionオプション
collectionオプションを使用するとcollectionオプションに指定した変数の要素の分だけ部分テンプレートが繰り返し表示されます。
1
<%= render partial: 'hoge', collection: 繰り返し表示する要素が入っているインスタンス %>
先ほどの例だと@hoges
にはhogesテーブルから繰り返して表示させたいレコードを取得して代入してあります。
そうすると自動で一つ一つの要素が取り出され部分テンプレートに渡されて繰り返し表示されるという流れになります。
またcollectionオプションを使用する時はpartial:
を記述しないとエラーになるので気をつけましょう。
部分テンプレート内で使う変数を変更する場合
collectionオプションを使用した場合、部分テンプレート内で使用する変数はpartialで指定した名前になります。
もし別の名前として変数を使いたい場合は下記のように記述します。
1
<%= render partial: 'hoge', collection: @hoges, as: "fuga" %>
この時、@hoges
に入っている要素が一つずつ取り出され、部分テンプレート内の変数fuga
に代入されます。
asオプション
このように記述すると@hoges
の要素が一つずつfuga
という変数に代入され、部分テンプレート内で使用することができます。
パフォーマンスに注意しよう
繰り返し部分テンプレートを使う場合、each文の中に記述するかcollectionオプションを使うか2つの方法があるということがわかりました。
どちらを使っても問題なく表示されるのですが、決定的な違いがあります。
それはパフォーマンスの問題です。
collectionオプションを使用して記述すると部分テンプレートが呼び出されるのは1回のみなので、eachで表示するよりもパフォーマンスが良くなります。
では実際どれくらいの違いがあるのでしょうか?
2つの例で確認してみましょう。
上の例では1000回部分テンプレートを呼び出しました。
確認すると呼び出すのに合計で2945.8msかかっているのがわかります。
下の例はcollectionオプションを使った時の結果です。
collectionオプションを使うと1回しか読み込まれないので136.7msしかかかっていません。
1,000回呼び出すことはまずないと思いますが、これだけの差になってしまいます。
ですので部分テンプレートを繰り返し呼び出す時は出来るだけcollectionオプションを使う記述にしましょう。
省略した書き方
1
<%= render partial: 'hoge', collection: @hoges %>
上のコードは下の3つの条件を全て満たしている時、このコードを省略して書くことができます。
- 呼び出す部分テンプレートがviewsフォルダ内にある
hogesフォルダ
に存在する - 部分テンプレート名が
_hoge.html.erb
である - 部分テンプレート内で使う変数が
hoge
である
上の条件を全て満たしていると下記のように省略できます。
1
<%= render @hoges %>
このようにだいぶ短く書くことができます。
このコードは下のコードと全く同じ結果になります。
1
2
3
4
5
6
7
<!--下のコードと全く同じ -->
<%= render partial: 'hoge', collection: @hoges %>
<!--もしくは下のコードと全く同じ -->
<% @hoges.each do |hoge| %>
<%= render partial: 'hoge', hoge: hoge %>
<% end %>
この場合、viewsフォルダのhogesフォルダ内にある部分テンプレート_hoge.html.erb
を自動で選択してくれます。
かなり簡潔に書くことができますね!
部分テンプレートを使うメリット
部分テンプレートを使った時と使わない時ではビューの表示は全く変わりません。
それではなぜ部分テンプレートを使うのでしょうか?
部分テンプレートを使うメリットをいくつかあげてみます。
- 複数箇所で使われているコードに対し、同じ記述を書かなくてすむ
main_content
,footer
のように命名規則でどの部分の記述をしてるかコードを見なくてもわかる- 一つのファイルにコードを書き過ぎることがなくなり可読性が上がる
それではメリットを一つずつ確認していきましょう。
同じ記述を書かなくてすむ
例えばフォームに入力してもらう内容を変えたい場合、ファイルを編集する必要がありますね。
部分テンプレートを使う前だとnew.html.erb
とedit.html.erb
の2つのファイルを編集する必要がありました。
ですが部分テンプレートとして切り分けると部分テンプレートだけ編集すれば良いので作業効率が上がったり、修正ミスが少なくなるなどというメリットがあります。
コードをみなくても内容がわかる
部分テンプレートの名前をheader
やmenu
などの名前にしておくと、そのコードをみなくても「ああ、ここはヘッダーの部分なんだな」などコードの内容がとてもわかりやすくなります。
可読性が上がる
また一つのビューファイル自体が非常にコンパクトになります。
下の例を見てみましょう。
このようなビューファイルがあった時、上のメニューと右カラムは複数のビューファイルで使われているとします。
ですので部分テンプレートを作成し、ビューを切り分けてみましょう。
するとこのようにビューファイルがスッキリしましたね!
長いコードになってしまうとコードが非常に読みにくくなります。
できれば一つのビューファイルは100行以内に収まるようにするのが良いでしょう。
このように部分テンプレートを使うとビューの管理がだいぶ楽になります。
重複する箇所を見つけたら部分テンプレートしてまとめておきましょう。
この記事のまとめ
- 部分テンプレートとは、複数のビューファイルの中で使われている重複する部分を一つのビューファイルとして管理する時に使う
- 同じ記述を書かなくて済んだり、可読性が上がるメリットがある
- ファイル名の前に
_
(アンダースコア)をつける必要がある