Ruby on Railsのパーシャル(Partial)は、ビューの一部を別ファイルに切り出して再利用するための仕組みです。ヘッダーやフッター、フォームなど、複数のページで共通して使用するHTML部品をパーシャルとして定義しておくことで、コードの重複を減らし、メンテナンス性を大幅に向上させることができます。
基本的な使い方
パーシャルは、ファイル名の先頭にアンダースコア(_)を付けて作成します。例えば、ヘッダーのパーシャルは_header.html.erbというファイル名にします。
<div class="header">
<h1>サイトヘッダー</h1>
<nav>
<a href="/">ホーム</a>
<a href="/about">About</a>
</nav>
</div>このパーシャルを別のビューで読み込むには、renderメソッドを使用します。読み込む際はアンダースコアと拡張子を省略します。
<%= render "header" %>
<div class="content">
<p>メインコンテンツ</p>
</div>上記の<%= render "header" %>は、_header.html.erbの内容をその位置に埋め込みます。Railsが自動的にアンダースコアを付けたファイルを探してくれるため、ファイル名を正確に記述する必要はありません。
別のフォルダのパーシャルを読み込む
同じコントローラーのビューディレクトリだけでなく、別のフォルダにあるパーシャルも読み込めます。その場合は、app/views/からの相対パスを指定します。
<%= render "shared/header" %>
<%= render "shared/sidebar" %>
<div class="content">
<p>メインコンテンツ</p>
</div>
<%= render "shared/footer" %>この例では、app/views/shared/_header.html.erb、app/views/shared/_sidebar.html.erb、app/views/shared/_footer.html.erbがそれぞれ読み込まれます。sharedディレクトリは、複数のコントローラーで共有するパーシャルの置き場所として一般的に使われます。
パーシャルに変数を渡す
パーシャルにローカル変数を渡すことで、同じパーシャルを異なるデータで再利用できます。
<%= render "user_card", user: @current_user %>
<%= render "user_card", user: @admin_user %><div class="user-card">
<h3><%= user.name %></h3>
<p><%= user.email %></p>
</div>パーシャル内では、渡されたローカル変数(この例ではuser)を直接使用できます。localsオプションを使って明示的に渡す方法もあります。
<%= render partial: "user_card", locals: { user: @current_user, show_email: true } %>コレクションのレンダリング
配列やコレクションの各要素に対してパーシャルを繰り返しレンダリングする場合、collectionオプションを使うと効率的です。
<%= render partial: "post", collection: @posts %><div class="post">
<h2><%= post.title %></h2>
<p><%= post.content %></p>
<span><%= post.created_at.strftime("%Y/%m/%d") %></span>
</div>コレクションレンダリングでは、各要素がパーシャル名と同じ名前のローカル変数として自動的に渡されます。上記の例では、@postsの各要素がpost変数としてパーシャルに渡されます。さらに省略した書き方もあります。
<%= render @posts %>この省略記法は、Railsがモデル名からパーシャルのパスを自動的に推測してくれるため動作します。
パーシャルは機能単位で分割するのがベストプラクティスです。例えば、フォーム部分は_form.html.erb、一覧の1行分は_post.html.erbのように分けると、newとeditで同じフォームを再利用できます。
パーシャルのネストが深くなりすぎると、パフォーマンスが低下し、コードの追跡も困難になります。3階層以上のネストは避け、必要に応じてヘルパーメソッドやデコレーターで代替することを検討してください。
まとめ
- パーシャルはファイル名の先頭にアンダースコア(
_)を付けて作成する <%= render "パーシャル名" %>で読み込み(アンダースコアと拡張子は省略)- 別フォルダのパーシャルは
render "shared/header"のようにパスを指定する - ローカル変数を渡すことで同じパーシャルを異なるデータで再利用できる
collectionオプションでコレクションの繰り返しレンダリングが効率的にできる- フォームやカードなどの共通部品をパーシャル化してDRYを実現する