Question
ERB Tags in Rails: Difference Between <% %>, <%= %>, <%# %>, and -%>
Question
In a Rails ERB template, what is the difference between these tags, and when should each one be used?
<% %>
<%= %>
<% -%>
<%# %>
I would like a clear explanation of what each form does, especially how they affect output in the rendered HTML.
Short Answer
By the end of this page, you will understand how ERB tags work in Rails templates, which tags produce output, which tags only run Ruby code, how ERB comments behave, and what -%> does when trimming whitespace or newlines.
Concept
ERB stands for Embedded Ruby. It lets you write Ruby inside a text template, usually HTML in a Rails view.
The main idea is simple:
- some ERB tags run Ruby code without showing anything
- some tags run Ruby code and insert the result into the page
- some tags are comments
- some closing forms affect whitespace and newlines
Here are the core forms:
<% ... %>: execute Ruby code, but do not print the result<%= ... %>: execute Ruby code and output the result into the template<%# ... %>: ERB comment, ignored by ERB-%>: a variation of the closing tag used to trim a newline or surrounding whitespace depending on ERB configuration and usage
This matters because Rails views are not just static HTML. They often contain:
- loops
- conditionals
- helper calls
- partial rendering
- dynamic content
Choosing the right tag controls whether your Ruby logic affects the final HTML output or only the template flow.
Mental Model
Think of an ERB template like a theater script:
<% ... %>is a stage direction: it tells the actors what to do, but the audience does not hear it.<%= ... %>is a spoken line: it becomes part of what the audience sees or hears.<%# ... %>is a note in the script: only for the writer, not used in the performance.-%>is a cleanup instruction: it helps remove an extra blank line or unwanted spacing after the tag.
So the biggest question is always: Do I want this Ruby code to appear in the final HTML, or just control the template?
Syntax and Examples
Core syntax
<% ruby_code %>
<%= ruby_expression %>
<%# comment %>
<% ruby_code -%>
1. <% %> — run Ruby without output
Use this for logic such as if, each, variable assignment, or setup.
<% items = ["Apple", "Banana", "Cherry"] %>
<% items.each do |item| %>
<li><%= item %></li>
<% end %>
What happens?
items = [...]runs, but does not print anythingeach doandendcontrol the loop, but do not print anything<%= item %>prints each item inside the<li>
Rendered output:
<li>Apple</li>
<li>Banana</li>
<li>Cherry</li>
2. — run Ruby and output the result
Step by Step Execution
Consider this ERB template:
<% name = "Sam" %>
<p><%= name %></p>
<%# This is hidden %>
Step-by-step
Line 1
<% name = "Sam" %>
- Ruby assigns the string
"Sam"toname - Nothing is printed into the HTML
Line 2
<p><%= name %></p>
- ERB evaluates
name - The value
Samis inserted into the template
So this becomes:
<p>Sam</p>
Line 3
<%# This is hidden %>
- ERB treats this as a comment
- It is ignored and does not appear in the output
Final rendered result
<>Sam
Real World Use Cases
ERB tags are used constantly in Rails views.
Common scenarios
Showing dynamic data
<h1><%= @post.title %></h1>
<p><%= @post.body %></p>
Use <%= %> because the values must appear in the page.
Running loops
<% @posts.each do |post| %>
<h2><%= post.title %></h2>
<% end %>
Use <% %> for the loop itself, and <%= %> for what should be shown.
Conditional display
<% if current_user.admin? %>
<a href="/admin">Admin Panel</a>
<% end %>
Use <% %> because the if controls whether content is included.
Developer notes in templates
<%# Replace this with a reusable partial later %>
Use <%# %> for notes that should not appear in HTML.
Avoiding extra blank lines in generated text
This is more common in text-based templates such as emails, config files, or XML:
Real Codebase Usage
In real Rails codebases, developers use ERB tags in a few repeatable patterns.
1. Guarded rendering
<% if @order.present? %>
<p>Order total: <%= @order.total %></p>
<% end %>
- logic uses
<% %> - visible content uses
<%= %>
2. Iteration with helpers
<% @users.each do |user| %>
<li><%= link_to user.name, user_path(user) %></li>
<% end %>
Helpers like link_to are often placed inside <%= %> because they return HTML to render.
3. Partial rendering
<%= render "form", product: @product %>
render returns content, so it usually appears inside <%= %>.
4. Simple setup logic
<% css_class = @product.in_stock? ? "available" : "sold-out" %>
<div class="<%= css_class %>">
<%= @product.name %>
</div>
Assignment uses <% %>; output uses <%= %>.
Common Mistakes
1. Using <% %> when you meant to print something
Broken example:
<p><% @user.name %></p>
Problem:
- the code runs, but nothing is output
Correct version:
<p><%= @user.name %></p>
2. Using <%= %> for control flow keywords
Broken example:
<%= if @user.admin? %>
<p>Admin</p>
<%= end %>
Problem:
ifandendare control-flow structure, not content to print- this is invalid or confusing
Correct version:
<% if @user.admin? %>
<p>Admin</p>
<% end %>
3. Forgetting that comments differ
An HTML comment is still sent to the browser:
<!-- secret note -->
If you do not want it in the rendered HTML, use an ERB comment:
<%# secret note %>
Comparisons
| Tag | Runs Ruby? | Outputs result? | Appears in final HTML? | Typical use |
|---|---|---|---|---|
<% ... %> | Yes | No | No | loops, if, variable assignment |
<%= ... %> | Yes | Yes | Yes | display values, helpers, rendered partials |
<%# ... %> | No meaningful output | No | No | template comments |
-%> | Yes, as part of another tag | Depends on tag type | Depends on tag type |
Cheat Sheet
<% ruby_code %>
- Runs Ruby
- Does not print anything
- Use for
if,each, variable assignment,end
<%= expression %>
- Runs Ruby
- Prints the result into the template
- Use for variables, helper output,
render, formatted values
<%# comment %>
- ERB comment
- Not rendered
- Good for developer notes inside templates
<% code -%>
- Same as normal ERB code, but trims newline/whitespace in supported contexts
- Mainly useful for formatting clean output
Quick rule
- logic only:
<% %> - show result:
<%= %> - leave note:
<%# %> - control whitespace:
-%>
Example
FAQ
What does <% %> do in Rails ERB?
It executes Ruby code without inserting the result into the rendered HTML.
What does <%= %> do in ERB?
It executes Ruby and outputs the result into the template.
What is <%# %> used for in ERB?
It creates an ERB comment that is ignored during rendering and does not appear in the final HTML.
What does -%> mean in ERB?
It is a trimming form of the closing tag, used to remove an extra newline or whitespace in some ERB contexts.
Why is nothing showing when I use <% @name %>?
Because <% %> runs code without output. Use <%= @name %> if you want the value displayed.
Should I use ERB comments or HTML comments?
Use ERB comments for developer-only notes. Use HTML comments only if the comment should remain in the rendered page source.
Can I use if with <%= %>?
Usually no. Use <% if condition %> for control flow, then use <%= %> inside the block for visible content.
Does Rails still use ERB often?
Mini Project
Description
Build a small Rails-style ERB template for a product list. This project helps you practice the difference between running Ruby logic, printing values, adding comments, and trimming whitespace where needed.
Goal
Create an ERB template that loops through products, shows only available ones, prints their names and prices, and includes a developer-only note.
Requirements
- Create an array of product hashes or objects with name, price, and availability values.
- Use
<% %>for the loop and conditional logic. - Use
<%= %>to display the product name and price. - Use
<%# %>to add a comment that does not appear in the output. - Use
-%>on at least one line to practice whitespace trimming.
Keep learning
Related questions
Calling a Class Method from an Instance in Ruby
Learn how to call a class method from an instance in Ruby using self.class, with examples, pitfalls, and practical usage patterns.
Calling an Overridden Monkey-Patched Method in Ruby
Learn how to call the original method when monkey patching in Ruby, including alias_method patterns, examples, pitfalls, and practical usage.
Convert a Unix Timestamp to Ruby DateTime
Learn how to convert Unix timestamps to Ruby DateTime and Time objects, with examples, differences, pitfalls, and practical Ruby usage.