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 <. 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 # JSONKeep 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.
The symptom
The list items appear but are empty.
Drills
Answer fast — trust the rule.
Which tag prints a book's title into the page?
Which tag should open an if in a template?
A review body contains <b>great</b> and is shown with <%= review.body %>. What does the visitor see?
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.
