Pebellslearn by building
0%
RoadmapsMatrixCoursesSandboxSign in
Action View  ›  Lesson

ERB Templates and Rendering Views

ERB Templates 12 minERB mixes Ruby into HTML: <%= %> prints an escaped value, <% %> runs code without printing, and Rails renders the template named after the action unless told otherwise.

ERB Templates and Rendering Views

The controller has found the books. Now they must become HTML. Rails views are mostly plain HTML with small windows where Ruby runs, written in a format called ERB (Embedded Ruby). Two tags do nearly all the work, and the difference between them is a single =.

The rule

<%= %> prints, <% %> only runs — and printing is escaped.

<%# app/views/books/index.html.erb %>
<h1>Books (<%= @books.size %>)</h1>

<% if @books.empty? %>
  <p>No books yet.</p>
<% else %>
  <ul>
    <% @books.each do |book| %>
      <li><%= book.title %> by <%= book.author %></li>
    <% end %>
  </ul>
<% end %>
  • <%= expression %> — runs Ruby and inserts the result into the page.
  • <% code %> — runs Ruby and prints nothing: loops, if, end.
  • <%# comment %> — ignored.

Everything printed with <%= %> is HTML-escaped: < becomes &lt;. If a member's review contains a <script> tag, the page shows the text instead of running it. This protects you from cross-site scripting. raw and .html_safe switch escaping off; reserve them for HTML your own code produced.

Rendering: the file name tells Rails what it is. index.html.erb is the index action's template, HTML format, ERB handler. By default BooksController#index renders app/views/books/index.html.erb. From an action you can choose another:

render :edit                       # books/edit.html.erb
render "shared/empty"              # another folder
render plain: "OK"                 # just text
render json: @book                 # JSON

Keep logic out of templates. A view that calls Book.where(...) is doing the controller's job; a view doing sums is doing the model's.

The shortcut

For each Ruby snippet in a template ask "should the reader see its result?" Yes → <%= %>. No, it is control flow → <% %>. The classic mistake shows up either way: <%= @books.each do |book| %> dumps the whole array on the page, and <% book.title %> prints nothing.

Fixing a page that shows nothingStep 1 of 4
  1. The symptom

    The list items appear but are empty.

Drills

Answer fast — trust the rule.

quick drill

Which tag prints a book's title into the page?

quick drill

Which tag should open an if in a template?

quick drill

A review body contains <b>great</b> and is shown with <%= review.body %>. What does the visitor see?

quick drill

BooksController#show does not call render. Which file is rendered?

Remember

  • <%= %> prints, <% %> only runs — and printing is escaped.
  • Shortcut: should the reader see the result? Then add the =.
  • Trap: raw and html_safe on user input; logic that belongs in the controller or model.

Practice — level up

0/1 solved

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

ExplainWhy did the script not run?

A member writes a review whose body is <script>alert('hi')</script>. The show page uses <%= review.body %>. Explain what the page displays and why, what would change with raw or html_safe, and when (if ever) you would use them.