経緯
ずっと苦手意識のあった部分テンプレートと向き合った結果、「なにこれ、便利!!」となったため、備忘録のために記事にします。
hamlで書いた記事があまりなかったり、localオプションの変数の意味や、collection、asの詳しい説明をなかなか見つけられなかったので、同じことで悩んでいる誰かのお役に立てたらすごく嬉しいです。
もくじ
- 部分テンプレートとは
- ファイル名
- hamlへの記載方法
- オプション
- partial
- locals
- collection
- as
- まとめ
部分テンプレートとは
部分テンプレート(=パーシャル)とは、繰り返し使用される要素をまとめてテンプレート化するもの。何度も同じコードを書くことを防ぐことができる。また、投稿一覧画面を作成する際、collectionオプションを使用すると、each分を使わずに繰り返しができ、読み込み速度もeach文を使用する時より速い(らしい)。
ファイル名
部分テンプレートのファイル名は、必ずファイル名の最初に**「_(アンダーバー)」**をつける。アンダーバーをつけることで、当該のファイルが部分テンプレートであることを明示的に表せる。
#hamlへの記載方法
部分テンプレートを呼び出す際、呼び出す側のファイルに以下の通りに記載し、呼び出される部分テンプレートを指定する。
例:
呼び出す側のファイル index.html.haml
呼び出される部分テンプレートファイル **_**post_index.html.haml
.post__index
= render partial: 'post_index'
' '内に記載するファイル名は、「_」を省いて記載。
#オプション
部分テンプレートには、様々な便利なオプションがあるため、紹介。
###partialオプション
前項の通り、呼び出される部分テンプレートを指定するオプション。
尚、呼び出す側のファイルと部分テンプレートが異なるディレクトリにある場合は、ディレクトリ名も含めて指定する必要がある。
例:
呼び出す側のファイル view/posts/index.html.haml
呼び出される部分テンプレートファイル view/shared/_post_index.html.haml
.post__index
= render partial: 'shared/post_index'
###localオプション
部分テンプレート内で使う変数(ローカル変数)を定義するオプション。
.post__index
= render partial: 'post_index', local: { posts: @posts }
-省略形は
= render 'post_index', posts: @posts
{ posts: @posts } の
postsは部分テンプレート内で使用する変数(=ローカル変数)。
@postsは、postsコントローラのindexアクションで定義した変数。
=呼び出した側のファイル(postディレクトリのindex.html.haml)で使えるよう、コントローラで定義した変数。
つまり、部分テンプレート内でpostsを使用した場合、その変数の中身は、postsコントローラのindexアクションで定義された@postを同義となる。
each文を使用し、一つの投稿を繰り返し表示さのせレバ、投稿一覧ベージの完成。
- posts.each do |post|
.post__index__content
.post__index__header
.post__index__header--user-name
= post.user.name
.post__index__header--btn
= link_to edit_post_path(post.id) do
%i.fa.fa-edit<>
= link_to post_path(post.id), method: :delete do
%i.fa.fa-trash
.post__index__content--image
- if post.image.present?
= image_tag post.image.to_s, size: "400x400"
.post__index__content--text
= post.text
###collectionオプション
このオプション、めちゃ便利! 今回のような投稿一覧を作成する際、普通はビューでeach文を使用して、@postsの中にあるデータを取り出す。しかし、collestionオプションを使用すると、each文を書かずとも、繰り返してくれる。
.post__index
= render partial: 'post_index', collection: @posts
このように定義することで、部分テンプレートでは、以下の記述のみでOK。
.post__index__content
.post__index__header
.post__index__header--user-name
= post_index.user.name
.post__index__header--btn
= link_to edit_post_path(post.id) do
%i.fa.fa-edit<>
= link_to post_path(post.id), method: :delete do
%i.fa.fa-trash
.post__index__content--image
- if post_index.image.present?
= image_tag post.image.to_s, size: "400x400"
.post__index__content--text
= post_index.text
localオプションを使用した際に、一番上に記述があったeach文は不要。@posts(postsコントローラのindexアクションで定義した変数)を、一つずつ取り出して表示してくれる。
ちなみに、このように記述した場合、ローカル変数名は、「post_index(部分テンプレートのファイル名)」になることに注意。
###asオプション
前項で説明したcollectionオプションを使用した場合、ローカル変数名は部分テンプレートのファイル名になる。変数名を自分で指定したい場合に、asオプションを使用する。
.post__index
= render partial: 'post_index', collection: @posts, as: post
このように記述することで、前項でpost_indexと記述した箇所をpostに書き換えることができます。
.post__index__content
.post__index__header
.post__index__header--user-name
= post.user.name
.post__index__header--btn
= link_to edit_post_path(post.id) do
%i.fa.fa-edit<>
= link_to post_path(post.id), method: :delete do
%i.fa.fa-trash
.post__index__content--image
- if post.image.present?
= image_tag post.image.to_s, size: "400x400"
.post__index__content--text
= post.text
#まとめ
この他にも、便利なオプションがたくさんあるようだけど、今理解できているのはここまで。
新しいことを学んだら、追記します。
何か誤りがあれば、ご指摘いただけると嬉しいです。