3
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

部分テンプレートについて

Last updated at Posted at 2019-06-08

#部分テンプレートとは?

部分テンプレートとは、
共通化しているHTML構造の部分を一括にまとめたものを部分テンプレートという。

共通化しているHTML構造の部分とは、
例えば、Twitterやfacebookのように、一つ一つのツイート構造は、以下の画像のように、トップに名前、横に画像、下にコメントテキスト、というようにまとまった形式をとっている。
https://gyazo.com/d80d3a6d9e44378319bc47bea2122f67

これが、共通化しているHTML構造の部分のことである。

#部分テンプレートのメリット

部分テンプレートのメリットとして以下のようなメリットがある。
・繰り返し再利用できる
・繰り返し書くコードを一回で済ます
・修正するときに修正箇所が少なく済む

また、ブログやチャットアプリで使えるコメントやメッセージでは、ユーザーの数が多くなればなるほど、特定のビューを複数回使い回す回数が増える。そのため、eachメソッドを用いて情報を一つ一つ呼び出すよりも、部分テンプレートをrenderメソッドでまとめて呼び出す方が、動作の速度が上がる。
よって、ブログやチャットアプリを作成する時は、大量のメッセージをやり取りすることが予想されるため、部分テンプレートを用いて実装をすることがオススメである。

#部分テンプレートの作成方法

既存のHTMLファイルから共通部分を切り出してコピーする。
以下のコードは、簡易なツイートアプリのコード

tweets/index.html.erb

<div class="contents row">
  <% @tweets.each do |tweet| %>
    <div class="content_post" style="background-image: url(<%= tweet.image %>);">
      <div class="more">
        <span><%= image_tag 'arrow_top.png' %></span>
        <ul class="more_list">
          <li>
            <%= link_to "詳細", tweet_path(tweet.id), method: :get %>
          </li>
          <% if user_signed_in? && current_user.id == tweet.user_id %>
            <li>
              <%= link_to '編集', "/tweets/#{tweet.id}/edit", method: :get %>
            </li>
            <li>
              <%= link_to '削除', "/tweets/#{tweet.id}", method: :delete %>
            </li>
          <% end %>
        </ul>
      </div>
      <%= simple_format(tweet.text) %>
      <span class="name">
        <a href="/users/<%= tweet.user_id %>">
          <span>投稿者</span><%= tweet.user.nickname %>
        </a>
      </span>
    </div>
  <% end %>
  <%= paginate(@tweets) %>
</div>

上記の例では、以下の部分を部分テンプレートとして切り出す

_tweet.html.erb

div class="content_post" style="background-image: url(<%= tweet.image %>);">
      <div class="more">
        <span><%= image_tag 'arrow_top.png' %></span>
        <ul class="more_list">
          <li>
            <%= link_to "詳細", tweet_path(tweet.id), method: :get %>
          </li>
          <% if user_signed_in? && current_user.id == tweet.user_id %>
            <li>
              <%= link_to '編集', "/tweets/#{tweet.id}/edit", method: :get %>
            </li>
            <li>
              <%= link_to '削除', "/tweets/#{tweet.id}", method: :delete %>
            </li>
          <% end %>
        </ul>
      </div>
      <%= simple_format(tweet.text) %>
      <span class="name">
        <a href="/users/<%= tweet.user_id %>">
          <span>投稿者</span><%= tweet.user.nickname %>
        </a>
      </span>
    </div>

ビューフォルダーに部分テンプレートファイルを作る。
そして、切り出した共通部分を貼り付ける。
部分テンプレートのファイル名をつけるときは、必ずアンダーバー「_」をつけること。

#部分テンプレートの呼び出し方法

部分テンプレートを呼び出すためには、renderメソッドを使う必要がある。
具体的には、render partialオプションを使う。
これは、メソッドに :partialというオプションをつけることで、明示的に部分テンプレート名を指定し、部分テンプレートを表示することができるものである。

tweets/index.html.erb

<div class="contents row">
  <% @tweets.each do |tweet| %>
    <%= render partial: "tweet", locals: { tweet: tweet } %>
  <% end %>
  <%= paginate(@tweets) %>
</div>

上記の例でいえば、以下のような記述になる。

render partial: "tweet"

また、render localsオプションを用いることで、部分テンプレート内において変数を使えるようになる。render localsオプションの使い方は、render partialオプションの後に続けて記述する。


<%= render partial: "tweet", locals: { tweet: tweet } %>

そして、locals: の右側の{ tweet: tweet }の記述において、右側のtweetは、eachメソッド内の変数としてのtweetを表している。一方、左側のtweetは、部分テンプレート内での変数の名前を表している。

#render時の記述の省略方法


= render partial: '部分テンプレート名', collection: @インスタンス変数名

複数形のインスタンス変数を部分テンプレートに渡したい場合、インスタンス変数の名前を単数形にしたものと、部分テンプレートの名前が同じなら、「render インスタンス変数」と省略形で記述することができる。

                              
                                 以上

3
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?