Pebellslearn by building
0%
RoadmapsMatrixCoursesSandboxSign in
Action View  ›  Lesson

Partials and Helpers

Partials 15 minPartials are reusable template fragments whose file names start with an underscore, and helpers are Ruby methods that views call to format values or build small pieces of HTML.

Partials and Helpers

The review card on the book page and the review card on a member's profile should look identical. So should the book form on the "new" and "edit" pages. Views have two tools for not repeating yourself: partials for chunks of HTML, and helpers for small bits of Ruby logic.

The rule

Repeat HTML → a partial; repeat logic → a helper.

A partial is a template whose file name starts with an underscore:

<%# app/views/reviews/_review.html.erb %>
<article class="review">
  <p><%= stars(review.rating) %> by <%= review.member.name %></p>
  <p><%= review.body %></p>
  <small><%= time_ago_in_words(review.created_at) %> ago</small>
</article>

Render it without the underscore:

<%= render "reviews/review", review: @review %>   <%# one, passing a local %>
<%= render @book.reviews %>                        <%# a whole collection %>
<%= render @review %>                              <%# one record, by convention %>

render @book.reviews looks at the class, finds reviews/_review.html.erb, and renders it once per review with a local variable named review. If the collection is empty it returns nil, so <%= render(@book.reviews) || "No reviews yet" %> handles both cases.

Inside a partial, use locals (review), not instance variables (@review). Then the partial works wherever it is rendered.

A helper is a method available in every view. Rails ships many:

<%= link_to "Edit", edit_book_path(@book) %>
<%= number_to_currency(@book.price) %>              <%# $12.50 %>
<%= pluralize(@book.reviews.size, "review") %>      <%# 1 review, 3 reviews %>
<%= truncate(review.body, length: 80) %>
<%= time_ago_in_words(review.created_at) %>

Your own go in app/helpers:

# app/helpers/reviews_helper.rb
module ReviewsHelper
  def stars(rating)
    "★" * rating + "☆" * (5 - rating)
  end
end

The shortcut

Look for the same thing twice. Twice the same markup → cut it into a partial, turn @ variables into locals. Twice the same formatting call chain → a helper method.

Sharing the book formStep 1 of 4
  1. Spot the repeat

    new.html.erb and edit.html.erb contain the same form.

The trap is a partial that reads @book directly. It silently depends on whichever controller rendered it, and breaks on a page that uses another name.

Drills

Answer fast — trust the rule.

quick drill

What is the file name for a partial rendered with render "books/card"?

quick drill

Inside reviews/_review.html.erb, what does <%= render @book.reviews %> provide for each item?

quick drill

Which built-in helper turns 3 into "3 reviews" and 1 into "1 review"?

quick drill

A partial should work on several pages. What should it read its data from?

Remember

  • Repeat HTML → a partial; repeat logic → a helper.
  • Shortcut: same thing twice → extract it; @ variables become locals.
  • Trap: partials that depend on a controller's instance variables.

Practice — level up

0/1 solved

Write your answer, then compare it with a rubric and a model answer.

ExplainOne partial, two pages

A review card appears on the book page and on the member's profile page. Explain how to write it once as a partial, how both pages render a list of reviews with one line, and how you would show each review's star rating using a helper.